QGIS API Documentation
3.26.3-Buenos Aires (65e4edfdad)
|
Go to the documentation of this file.
33 #include <QSvgRenderer>
36 #include <QDomDocument>
37 #include <QDomElement>
44 static constexpr
int MAX_FONT_CHARACTER_SIZE_IN_PIXELS = 500;
46 static void _fixQPictureDPI( QPainter *p )
52 p->scale(
static_cast< double >(
qt_defaultDpiX() ) / p->device()->logicalDpiX(),
53 static_cast< double >(
qt_defaultDpiY() ) / p->device()->logicalDpiY() );
66 QList< Qgis::MarkerShape > shapes;
165 QTransform transform;
168 if ( !hasDataDefinedSize )
178 const double half = scaledSize / 2.0;
179 transform.scale( half, half );
185 transform.rotate(
mAngle );
212 bool hasDataDefinedSize =
false;
213 const double scaledSize =
calculateSize( context, hasDataDefinedSize );
215 bool hasDataDefinedRotation =
false;
221 bool createdNewPath =
false;
228 if ( !exprVal.isNull() )
239 createdNewPath =
true;
248 QTransform transform;
251 transform.translate( point.x() +
offset.x(), point.y() +
offset.y() );
254 if ( hasDataDefinedSize || createdNewPath )
263 const double half = s / 2.0;
264 transform.scale( half, half );
269 transform.rotate(
angle );
278 polygon = transform.map(
mPolygon );
282 path = transform.map(
mPath );
284 draw( context, symbol, polygon, path );
289 bool hasDataDefinedSize =
false;
290 double scaledSize =
calculateSize( context, hasDataDefinedSize );
292 bool hasDataDefinedRotation =
false;
299 QTransform transform;
302 transform.translate( point.x() +
offset.x(), point.y() +
offset.y() );
305 transform.rotate(
angle );
307 return transform.mapRect( QRectF( -scaledSize / 2.0,
317 const QString cleaned = name.toLower().trimmed();
319 if ( cleaned == QLatin1String(
"square" ) || cleaned == QLatin1String(
"rectangle" ) )
321 else if ( cleaned == QLatin1String(
"square_with_corners" ) )
323 else if ( cleaned == QLatin1String(
"diamond" ) )
325 else if ( cleaned == QLatin1String(
"pentagon" ) )
327 else if ( cleaned == QLatin1String(
"hexagon" ) )
329 else if ( cleaned == QLatin1String(
"octagon" ) )
331 else if ( cleaned == QLatin1String(
"triangle" ) )
333 else if ( cleaned == QLatin1String(
"equilateral_triangle" ) )
335 else if ( cleaned == QLatin1String(
"star" ) || cleaned == QLatin1String(
"regular_star" ) )
337 else if ( cleaned == QLatin1String(
"arrow" ) )
339 else if ( cleaned == QLatin1String(
"circle" ) )
341 else if ( cleaned == QLatin1String(
"cross" ) )
343 else if ( cleaned == QLatin1String(
"cross_fill" ) )
345 else if ( cleaned == QLatin1String(
"cross2" ) || cleaned == QLatin1String(
"x" ) )
347 else if ( cleaned == QLatin1String(
"line" ) )
349 else if ( cleaned == QLatin1String(
"arrowhead" ) )
351 else if ( cleaned == QLatin1String(
"filled_arrowhead" ) )
353 else if ( cleaned == QLatin1String(
"semi_circle" ) )
355 else if ( cleaned == QLatin1String(
"third_circle" ) )
357 else if ( cleaned == QLatin1String(
"quarter_circle" ) )
359 else if ( cleaned == QLatin1String(
"quarter_square" ) )
361 else if ( cleaned == QLatin1String(
"half_square" ) )
363 else if ( cleaned == QLatin1String(
"diagonal_half_square" ) )
365 else if ( cleaned == QLatin1String(
"right_half_triangle" ) )
367 else if ( cleaned == QLatin1String(
"left_half_triangle" ) )
369 else if ( cleaned == QLatin1String(
"asterisk_fill" ) )
371 else if ( cleaned == QLatin1String(
"half_arc" ) )
373 else if ( cleaned == QLatin1String(
"third_arc" ) )
375 else if ( cleaned == QLatin1String(
"quarter_arc" ) )
388 return QStringLiteral(
"square" );
390 return QStringLiteral(
"quarter_square" );
392 return QStringLiteral(
"half_square" );
394 return QStringLiteral(
"diagonal_half_square" );
396 return QStringLiteral(
"diamond" );
398 return QStringLiteral(
"pentagon" );
400 return QStringLiteral(
"hexagon" );
402 return QStringLiteral(
"octagon" );
404 return QStringLiteral(
"square_with_corners" );
406 return QStringLiteral(
"triangle" );
408 return QStringLiteral(
"equilateral_triangle" );
410 return QStringLiteral(
"left_half_triangle" );
412 return QStringLiteral(
"right_half_triangle" );
414 return QStringLiteral(
"star" );
416 return QStringLiteral(
"arrow" );
418 return QStringLiteral(
"filled_arrowhead" );
420 return QStringLiteral(
"cross_fill" );
422 return QStringLiteral(
"circle" );
424 return QStringLiteral(
"cross" );
426 return QStringLiteral(
"cross2" );
428 return QStringLiteral(
"line" );
430 return QStringLiteral(
"arrowhead" );
432 return QStringLiteral(
"semi_circle" );
434 return QStringLiteral(
"third_circle" );
436 return QStringLiteral(
"quarter_circle" );
438 return QStringLiteral(
"asterisk_fill" );
440 return QStringLiteral(
"half_arc" );
442 return QStringLiteral(
"third_arc" );
444 return QStringLiteral(
"quarter_arc" );
461 polygon = QPolygonF( QRectF( QPointF( -1, -1 ), QPointF( 1, 1 ) ) );
466 static constexpr
double VERTEX_OFFSET_FROM_ORIGIN = 0.6072;
468 polygon << QPointF( - VERTEX_OFFSET_FROM_ORIGIN, 1 )
469 << QPointF( VERTEX_OFFSET_FROM_ORIGIN, 1 )
470 << QPointF( 1, VERTEX_OFFSET_FROM_ORIGIN )
471 << QPointF( 1, -VERTEX_OFFSET_FROM_ORIGIN )
472 << QPointF( VERTEX_OFFSET_FROM_ORIGIN, -1 )
473 << QPointF( -VERTEX_OFFSET_FROM_ORIGIN, -1 )
474 << QPointF( -1, -VERTEX_OFFSET_FROM_ORIGIN )
475 << QPointF( -1, VERTEX_OFFSET_FROM_ORIGIN )
476 << QPointF( -VERTEX_OFFSET_FROM_ORIGIN, 1 );
481 polygon = QPolygonF( QRectF( QPointF( -1, -1 ), QPointF( 0, 0 ) ) );
485 polygon = QPolygonF( QRectF( QPointF( -1, -1 ), QPointF( 0, 1 ) ) );
489 polygon << QPointF( -1, -1 ) << QPointF( 1, 1 ) << QPointF( -1, 1 ) << QPointF( -1, -1 );
493 polygon << QPointF( -1, 0 ) << QPointF( 0, 1 )
494 << QPointF( 1, 0 ) << QPointF( 0, -1 ) << QPointF( -1, 0 );
504 polygon << QPointF( -0.9511, -0.3090 )
505 << QPointF( -0.5878, 0.8090 )
506 << QPointF( 0.5878, 0.8090 )
507 << QPointF( 0.9511, -0.3090 )
509 << QPointF( -0.9511, -0.3090 );
520 polygon << QPointF( -0.8660, -0.5 )
521 << QPointF( -0.8660, 0.5 )
523 << QPointF( 0.8660, 0.5 )
524 << QPointF( 0.8660, -0.5 )
526 << QPointF( -0.8660, -0.5 );
531 static constexpr
double VERTEX_OFFSET_FROM_ORIGIN = 1.0 / ( 1 + M_SQRT2 );
533 polygon << QPointF( - VERTEX_OFFSET_FROM_ORIGIN, 1 )
534 << QPointF( VERTEX_OFFSET_FROM_ORIGIN, 1 )
535 << QPointF( 1, VERTEX_OFFSET_FROM_ORIGIN )
536 << QPointF( 1, -VERTEX_OFFSET_FROM_ORIGIN )
537 << QPointF( VERTEX_OFFSET_FROM_ORIGIN, -1 )
538 << QPointF( -VERTEX_OFFSET_FROM_ORIGIN, -1 )
539 << QPointF( -1, -VERTEX_OFFSET_FROM_ORIGIN )
540 << QPointF( -1, VERTEX_OFFSET_FROM_ORIGIN )
541 << QPointF( -VERTEX_OFFSET_FROM_ORIGIN, 1 );
546 polygon << QPointF( -1, 1 ) << QPointF( 1, 1 ) << QPointF( 0, -1 ) << QPointF( -1, 1 );
554 polygon << QPointF( -0.8660, 0.5 )
555 << QPointF( 0.8660, 0.5 )
557 << QPointF( -0.8660, 0.5 );
561 polygon << QPointF( 0, 1 ) << QPointF( 1, 1 ) << QPointF( 0, -1 ) << QPointF( 0, 1 );
565 polygon << QPointF( -1, 1 ) << QPointF( 0, 1 ) << QPointF( 0, -1 ) << QPointF( -1, 1 );
570 const double inner_r = std::cos(
DEG2RAD( 72.0 ) ) / std::cos(
DEG2RAD( 36.0 ) );
572 polygon << QPointF( inner_r * std::sin(
DEG2RAD( 324.0 ) ), - inner_r * std::cos(
DEG2RAD( 324.0 ) ) )
573 << QPointF( std::sin(
DEG2RAD( 288.0 ) ), - std::cos(
DEG2RAD( 288 ) ) )
574 << QPointF( inner_r * std::sin(
DEG2RAD( 252.0 ) ), - inner_r * std::cos(
DEG2RAD( 252.0 ) ) )
575 << QPointF( std::sin(
DEG2RAD( 216.0 ) ), - std::cos(
DEG2RAD( 216.0 ) ) )
576 << QPointF( 0, inner_r )
577 << QPointF( std::sin(
DEG2RAD( 144.0 ) ), - std::cos(
DEG2RAD( 144.0 ) ) )
578 << QPointF( inner_r * std::sin(
DEG2RAD( 108.0 ) ), - inner_r * std::cos(
DEG2RAD( 108.0 ) ) )
579 << QPointF( std::sin(
DEG2RAD( 72.0 ) ), - std::cos(
DEG2RAD( 72.0 ) ) )
580 << QPointF( inner_r * std::sin(
DEG2RAD( 36.0 ) ), - inner_r * std::cos(
DEG2RAD( 36.0 ) ) )
582 << QPointF( inner_r * std::sin(
DEG2RAD( 324.0 ) ), - inner_r * std::cos(
DEG2RAD( 324.0 ) ) );
587 polygon << QPointF( 0, -1 )
588 << QPointF( 0.5, -0.5 )
589 << QPointF( 0.25, -0.5 )
590 << QPointF( 0.25, 1 )
591 << QPointF( -0.25, 1 )
592 << QPointF( -0.25, -0.5 )
593 << QPointF( -0.5, -0.5 )
598 polygon << QPointF( 0, 0 ) << QPointF( -1, 1 ) << QPointF( -1, -1 ) << QPointF( 0, 0 );
602 polygon << QPointF( -1, -0.2 )
603 << QPointF( -1, -0.2 )
604 << QPointF( -1, 0.2 )
605 << QPointF( -0.2, 0.2 )
606 << QPointF( -0.2, 1 )
608 << QPointF( 0.2, 0.2 )
610 << QPointF( 1, -0.2 )
611 << QPointF( 0.2, -0.2 )
612 << QPointF( 0.2, -1 )
613 << QPointF( -0.2, -1 )
614 << QPointF( -0.2, -0.2 )
615 << QPointF( -1, -0.2 );
620 static constexpr
double THICKNESS = 0.3;
621 static constexpr
double HALF_THICKNESS = THICKNESS / 2.0;
622 static constexpr
double INTERSECTION_POINT = THICKNESS / M_SQRT2;
623 static constexpr
double DIAGONAL1 = M_SQRT1_2 - INTERSECTION_POINT * 0.5;
624 static constexpr
double DIAGONAL2 = M_SQRT1_2 + INTERSECTION_POINT * 0.5;
626 polygon << QPointF( -HALF_THICKNESS, -1 )
627 << QPointF( HALF_THICKNESS, -1 )
628 << QPointF( HALF_THICKNESS, -HALF_THICKNESS - INTERSECTION_POINT )
629 << QPointF( DIAGONAL1, -DIAGONAL2 )
630 << QPointF( DIAGONAL2, -DIAGONAL1 )
631 << QPointF( HALF_THICKNESS + INTERSECTION_POINT, -HALF_THICKNESS )
632 << QPointF( 1, -HALF_THICKNESS )
633 << QPointF( 1, HALF_THICKNESS )
634 << QPointF( HALF_THICKNESS + INTERSECTION_POINT, HALF_THICKNESS )
635 << QPointF( DIAGONAL2, DIAGONAL1 )
636 << QPointF( DIAGONAL1, DIAGONAL2 )
637 << QPointF( HALF_THICKNESS, HALF_THICKNESS + INTERSECTION_POINT )
638 << QPointF( HALF_THICKNESS, 1 )
639 << QPointF( -HALF_THICKNESS, 1 )
640 << QPointF( -HALF_THICKNESS, HALF_THICKNESS + INTERSECTION_POINT )
641 << QPointF( -DIAGONAL1, DIAGONAL2 )
642 << QPointF( -DIAGONAL2, DIAGONAL1 )
643 << QPointF( -HALF_THICKNESS - INTERSECTION_POINT, HALF_THICKNESS )
644 << QPointF( -1, HALF_THICKNESS )
645 << QPointF( -1, -HALF_THICKNESS )
646 << QPointF( -HALF_THICKNESS - INTERSECTION_POINT, -HALF_THICKNESS )
647 << QPointF( -DIAGONAL2, -DIAGONAL1 )
648 << QPointF( -DIAGONAL1, -DIAGONAL2 )
649 << QPointF( -HALF_THICKNESS, -HALF_THICKNESS - INTERSECTION_POINT )
650 << QPointF( -HALF_THICKNESS, -1 );
673 mPath = QPainterPath();
679 mPath.addEllipse( QRectF( -1, -1, 2, 2 ) );
683 mPath.arcTo( -1, -1, 2, 2, 0, 180 );
684 mPath.lineTo( 0, 0 );
688 mPath.arcTo( -1, -1, 2, 2, 90, 120 );
689 mPath.lineTo( 0, 0 );
693 mPath.arcTo( -1, -1, 2, 2, 90, 90 );
694 mPath.lineTo( 0, 0 );
698 mPath.moveTo( 1, 0 );
699 mPath.arcTo( -1, -1, 2, 2, 0, 180 );
703 mPath.moveTo( 0, -1 );
704 mPath.arcTo( -1, -1, 2, 2, 90, 120 );
708 mPath.moveTo( 0, -1 );
709 mPath.arcTo( -1, -1, 2, 2, 90, 90 );
713 mPath.moveTo( -1, 0 );
714 mPath.lineTo( 1, 0 );
715 mPath.moveTo( 0, -1 );
716 mPath.lineTo( 0, 1 );
720 mPath.moveTo( -1, -1 );
721 mPath.lineTo( 1, 1 );
722 mPath.moveTo( 1, -1 );
723 mPath.lineTo( -1, 1 );
727 mPath.moveTo( 0, -1 );
728 mPath.lineTo( 0, 1 );
732 mPath.moveTo( -1, -1 );
733 mPath.lineTo( 0, 0 );
734 mPath.lineTo( -1, 1 );
762 double scaledSize =
mSize;
766 if ( hasDataDefinedSize )
773 if ( hasDataDefinedSize && ok )
778 scaledSize = std::sqrt( scaledSize );
793 markerOffset( context, scaledSize, scaledSize, offsetX, offsetY );
794 offset = QPointF( offsetX, offsetY );
796 hasDataDefinedRotation =
false;
809 hasDataDefinedRotation =
true;
814 if ( hasDataDefinedRotation )
843 , mStrokeColor( strokeColor )
844 , mPenJoinStyle( penJoinStyle )
861 if ( props.contains( QStringLiteral(
"name" ) ) )
865 if ( props.contains( QStringLiteral(
"color" ) ) )
867 if ( props.contains( QStringLiteral(
"color_border" ) ) )
872 else if ( props.contains( QStringLiteral(
"outline_color" ) ) )
876 else if ( props.contains( QStringLiteral(
"line_color" ) ) )
880 if ( props.contains( QStringLiteral(
"joinstyle" ) ) )
884 if ( props.contains( QStringLiteral(
"size" ) ) )
885 size = props[QStringLiteral(
"size" )].toDouble();
886 if ( props.contains( QStringLiteral(
"angle" ) ) )
887 angle = props[QStringLiteral(
"angle" )].toDouble();
888 if ( props.contains( QStringLiteral(
"scale_method" ) ) )
892 if ( props.contains( QStringLiteral(
"offset" ) ) )
894 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
896 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
898 if ( props.contains( QStringLiteral(
"size_unit" ) ) )
900 if ( props.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
903 if ( props.contains( QStringLiteral(
"outline_style" ) ) )
907 else if ( props.contains( QStringLiteral(
"line_style" ) ) )
911 if ( props.contains( QStringLiteral(
"outline_width" ) ) )
913 m->
setStrokeWidth( props[QStringLiteral(
"outline_width" )].toDouble() );
915 else if ( props.contains( QStringLiteral(
"line_width" ) ) )
917 m->
setStrokeWidth( props[QStringLiteral(
"line_width" )].toDouble() );
919 if ( props.contains( QStringLiteral(
"outline_width_unit" ) ) )
923 if ( props.contains( QStringLiteral(
"line_width_unit" ) ) )
927 if ( props.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
932 if ( props.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
936 if ( props.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
941 if ( props.contains( QStringLiteral(
"cap_style" ) ) )
954 return QStringLiteral(
"SimpleMarker" );
961 QColor brushColor =
mColor;
967 mBrush = QBrush( brushColor );
968 mPen = QPen( penColor );
978 selBrushColor.setAlphaF( context.
opacity() );
979 selPenColor.setAlphaF( context.
opacity() );
998 mCachedOpacity = context.
opacity();
1004 mSelPen.setColor( selBrushColor );
1036 scaledSize = ( std::abs( std::sin(
mAngle * M_PI / 180 ) ) + std::abs( std::cos(
mAngle * M_PI / 180 ) ) ) * scaledSize;
1039 const double pw =
static_cast< int >( std::round( ( (
qgsDoubleNear(
mPen.widthF(), 0.0 ) ? 1 :
mPen.widthF() * 4 ) + 1 ) ) ) / 2 * 2;
1040 const int imageSize = (
static_cast< int >( scaledSize ) + pw ) / 2 * 2 + 1;
1041 const double center = imageSize / 2.0;
1047 mCache = QImage( QSize( imageSize, imageSize ), QImage::Format_ARGB32_Premultiplied );
1054 p.setRenderHint( QPainter::Antialiasing );
1055 p.setBrush( needsBrush ?
mBrush : Qt::NoBrush );
1057 p.translate( QPointF( center, center ) );
1065 mSelCache = QImage( QSize( imageSize, imageSize ), QImage::Format_ARGB32_Premultiplied );
1069 p.setRenderHint( QPainter::Antialiasing );
1070 p.setBrush( needsBrush ?
mSelBrush : Qt::NoBrush );
1072 p.translate( QPointF( center, center ) );
1083 p.setRenderHint( QPainter::Antialiasing );
1084 p.fillRect( 0, 0, imageSize, imageSize, selColor );
1085 p.setBrush( needsBrush ?
mBrush : Qt::NoBrush );
1087 p.translate( QPointF( center, center ) );
1106 QColor brushColor =
mColor;
1107 brushColor.setAlphaF( brushColor.alphaF() * context.
opacity() );
1108 mBrush.setColor( brushColor );
1111 penColor.setAlphaF( penColor.alphaF() * context.
opacity() );
1112 mPen.setColor( penColor );
1121 c.setAlphaF(
c.alphaF() * context.
opacity() );
1131 c.setAlphaF(
c.alphaF() * context.
opacity() );
1183 p->setBrush( Qt::NoBrush );
1187 if ( !polygon.isEmpty() )
1188 p->drawPolygon( polygon );
1190 p->drawPath( path );
1207 const double s = img.width();
1209 bool hasDataDefinedSize =
false;
1210 const double scaledSize =
calculateSize( context, hasDataDefinedSize );
1212 bool hasDataDefinedRotation =
false;
1217 p->drawImage( QRectF( point.x() - s / 2.0 +
offset.x(),
1218 point.y() - s / 2.0 +
offset.y(),
1233 map[QStringLiteral(
"size" )] = QString::number(
mSize );
1236 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
1242 map[QStringLiteral(
"outline_width" )] = QString::number(
mStrokeWidth );
1275 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
1276 element.appendChild( graphicElem );
1285 const double angle = props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toDouble( &ok );
1288 angleFunc = QStringLiteral(
"%1 + %2" ).arg( props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toString() ).arg(
mAngle );
1303 Q_UNUSED( mmScaleFactor )
1304 Q_UNUSED( mapUnitScaleFactor )
1306 QString ogrType =
"3";
1307 if ( mName ==
"square" )
1311 else if ( mName ==
"triangle" )
1315 else if ( mName ==
"star" )
1319 else if ( mName ==
"circle" )
1323 else if ( mName ==
"cross" )
1327 else if ( mName ==
"x" || mName ==
"cross2" )
1331 else if ( mName ==
"line" )
1337 ogrString.append(
"SYMBOL(" );
1338 ogrString.append(
"id:" );
1339 ogrString.append(
'\"' );
1340 ogrString.append(
"ogr-sym-" );
1341 ogrString.append( ogrType );
1342 ogrString.append(
'\"' );
1343 ogrString.append(
",c:" );
1344 ogrString.append(
mColor.name() );
1345 ogrString.append(
",o:" );
1347 ogrString.append( QString(
",s:%1mm" ).arg(
mSize ) );
1348 ogrString.append(
')' );
1353 ogrString.append(
"PEN(" );
1354 ogrString.append(
"c:" );
1355 ogrString.append(
mColor.name() );
1356 ogrString.append(
",w:" );
1357 ogrString.append( QString::number(
mSize ) );
1358 ogrString.append(
"mm" );
1359 ogrString.append(
")" );
1367 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
1368 if ( graphicElem.isNull() )
1371 QString name = QStringLiteral(
"square" );
1384 const double d = angleFunc.toDouble( &ok );
1394 double scaleFactor = 1.0;
1395 const QString uom = element.attribute( QStringLiteral(
"uom" ) );
1422 p->drawPath(
mPath );
1435 if ( hasDataDefinedSize )
1456 size *= mmMapUnitScaleFactor;
1463 const double halfSize =
size / 2.0;
1480 QColor pc =
mPen.color();
1481 QColor bc =
mBrush.color();
1501 QPointF off( offsetX, offsetY );
1530 t.translate( shift.x() + off.x(), shift.y() - off.y() );
1538 t.scale( halfSize, -halfSize );
1540 polygon = t.map( polygon );
1543 p.reserve( polygon.size() );
1544 for (
int i = 0; i < polygon.size(); i++ )
1549 if (
mBrush.style() != Qt::NoBrush )
1551 if (
mPen.style() != Qt::NoPen )
1556 shift += QPointF( off.x(), -off.y() );
1557 if (
mBrush.style() != Qt::NoBrush )
1559 if (
mPen.style() != Qt::NoPen )
1564 const QPointF pt1 = t.map( QPointF( 0, -halfSize ) );
1565 const QPointF pt2 = t.map( QPointF( 0, halfSize ) );
1567 if (
mPen.style() != Qt::NoPen )
1572 if (
mPen.style() != Qt::NoPen )
1574 const QPointF pt1 = t.map( QPointF( -halfSize, 0 ) );
1575 const QPointF pt2 = t.map( QPointF( halfSize, 0 ) );
1576 const QPointF pt3 = t.map( QPointF( 0, -halfSize ) );
1577 const QPointF pt4 = t.map( QPointF( 0, halfSize ) );
1585 if (
mPen.style() != Qt::NoPen )
1587 const QPointF pt1 = t.map( QPointF( -halfSize, -halfSize ) );
1588 const QPointF pt2 = t.map( QPointF( halfSize, halfSize ) );
1589 const QPointF pt3 = t.map( QPointF( halfSize, -halfSize ) );
1590 const QPointF pt4 = t.map( QPointF( -halfSize, halfSize ) );
1598 if (
mPen.style() != Qt::NoPen )
1600 const QPointF pt1 = t.map( QPointF( -halfSize, halfSize ) );
1601 const QPointF pt2 = t.map( QPointF( 0, 0 ) );
1602 const QPointF pt3 = t.map( QPointF( -halfSize, -halfSize ) );
1688 symbolBounds.adjust( -penWidth / 2.0, -penWidth / 2.0,
1689 penWidth / 2.0, penWidth / 2.0 );
1691 return symbolBounds;
1740 if ( props.contains( QStringLiteral(
"name" ) ) )
1741 name = props[QStringLiteral(
"name" )].toString();
1742 if ( props.contains( QStringLiteral(
"size" ) ) )
1743 size = props[QStringLiteral(
"size" )].toDouble();
1744 if ( props.contains( QStringLiteral(
"angle" ) ) )
1745 angle = props[QStringLiteral(
"angle" )].toDouble();
1746 if ( props.contains( QStringLiteral(
"scale_method" ) ) )
1750 if ( props.contains( QStringLiteral(
"offset" ) ) )
1752 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
1754 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
1756 if ( props.contains( QStringLiteral(
"size_unit" ) ) )
1758 if ( props.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
1760 if ( props.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
1764 if ( props.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
1778 return QStringLiteral(
"FilledMarker" );
1803 map[QStringLiteral(
"size" )] = QString::number(
mSize );
1806 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
1862 attr.unite( mFill->usedAttributes( context ) );
1870 if ( mFill && mFill->hasDataDefinedProperties() )
1879 mFill->setColor(
c );
1884 return mFill ? mFill->color() :
mColor;
1891 || ( mFill && mFill->usesMapUnits() );
1898 mFill->setOutputUnit( unit );
1912 const double prevOpacity = mFill->opacity();
1913 mFill->setOpacity( mFill->opacity() * context.
opacity() );
1917 p->setBrush( Qt::red );
1921 p->setBrush( Qt::NoBrush );
1923 p->setPen( Qt::black );
1928 if ( !polygon.isEmpty() )
1934 const QPolygonF poly = path.toFillPolygon();
1940 mFill->setOpacity( prevOpacity );
1955 mColor = QColor( 35, 35, 35 );
1969 if ( props.contains( QStringLiteral(
"name" ) ) )
1970 name = props[QStringLiteral(
"name" )].toString();
1971 if ( props.contains( QStringLiteral(
"size" ) ) )
1972 size = props[QStringLiteral(
"size" )].toDouble();
1973 if ( props.contains( QStringLiteral(
"angle" ) ) )
1974 angle = props[QStringLiteral(
"angle" )].toDouble();
1975 if ( props.contains( QStringLiteral(
"scale_method" ) ) )
1980 if ( props.contains( QStringLiteral(
"size_unit" ) ) )
1982 if ( props.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
1984 if ( props.contains( QStringLiteral(
"fixedAspectRatio" ) ) )
1986 if ( props.contains( QStringLiteral(
"offset" ) ) )
1988 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
1990 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
1992 if ( props.contains( QStringLiteral(
"fill" ) ) )
1997 else if ( props.contains( QStringLiteral(
"color" ) ) )
2001 if ( props.contains( QStringLiteral(
"outline" ) ) )
2006 else if ( props.contains( QStringLiteral(
"outline_color" ) ) )
2010 else if ( props.contains( QStringLiteral(
"line_color" ) ) )
2015 if ( props.contains( QStringLiteral(
"outline-width" ) ) )
2018 m->
setStrokeWidth( props[QStringLiteral(
"outline-width" )].toDouble() );
2020 else if ( props.contains( QStringLiteral(
"outline_width" ) ) )
2022 m->
setStrokeWidth( props[QStringLiteral(
"outline_width" )].toDouble() );
2024 else if ( props.contains( QStringLiteral(
"line_width" ) ) )
2026 m->
setStrokeWidth( props[QStringLiteral(
"line_width" )].toDouble() );
2029 if ( props.contains( QStringLiteral(
"outline_width_unit" ) ) )
2033 else if ( props.contains( QStringLiteral(
"line_width_unit" ) ) )
2037 if ( props.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
2040 if ( props.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
2044 if ( props.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
2053 if ( props.contains( QStringLiteral(
"parameters" ) ) )
2055 const QVariantMap
parameters = props[QStringLiteral(
"parameters" )].toMap();
2064 const QVariantMap::iterator it =
properties.find( QStringLiteral(
"name" ) );
2083 QColor defaultFillColor, defaultStrokeColor;
2085 bool hasFillOpacityParam =
false, hasStrokeParam =
false, hasStrokeWidthParam =
false, hasStrokeOpacityParam =
false;
2086 bool hasDefaultFillColor =
false, hasDefaultFillOpacity =
false, hasDefaultStrokeColor =
false, hasDefaultStrokeWidth =
false, hasDefaultStrokeOpacity =
false;
2088 hasFillOpacityParam, hasDefaultFillOpacity, fillOpacity,
2089 hasStrokeParam, hasDefaultStrokeColor, defaultStrokeColor,
2090 hasStrokeWidthParam, hasDefaultStrokeWidth,
strokeWidth,
2091 hasStrokeOpacityParam, hasDefaultStrokeOpacity, strokeOpacity );
2093 const double newFillOpacity = hasFillOpacityParam ?
fillColor().alphaF() : 1.0;
2094 const double newStrokeOpacity = hasStrokeOpacityParam ?
strokeColor().alphaF() : 1.0;
2096 if ( hasDefaultFillColor )
2098 defaultFillColor.setAlphaF( newFillOpacity );
2101 if ( hasDefaultFillOpacity )
2104 c.setAlphaF( fillOpacity );
2107 if ( hasDefaultStrokeColor )
2109 defaultStrokeColor.setAlphaF( newStrokeOpacity );
2112 if ( hasDefaultStrokeWidth )
2116 if ( hasDefaultStrokeOpacity )
2119 c.setAlphaF( strokeOpacity );
2133 const double widthScaleFactor = 3.465;
2136 mDefaultAspectRatio = svgViewbox.isValid() ? svgViewbox.height() / svgViewbox.width() : 0.0;
2144 if ( aPreservedAspectRatio && !par )
2148 else if ( !aPreservedAspectRatio && par )
2163 return QStringLiteral(
"SvgMarker" );
2183 bool hasDataDefinedSize =
false;
2184 const double scaledWidth = calculateSize( context, hasDataDefinedSize );
2188 if (
static_cast< int >( width ) < 1 || 10000.0 < width )
2195 bool hasDataDefinedAspectRatio =
false;
2196 const double aspectRatio =
calculateAspectRatio( context, scaledWidth, hasDataDefinedAspectRatio );
2239 scaledHeight = svgViewbox.isValid() ? scaledWidth * svgViewbox.height() / svgViewbox.width() : scaledWidth;
2243 QPointF outputOffset;
2245 calculateOffsetAndRotation( context, scaledWidth, scaledHeight, outputOffset,
angle );
2247 p->translate( point + outputOffset );
2253 bool fitsInCache =
true;
2254 bool usePict =
true;
2261 if ( fitsInCache && img.width() > 1 )
2273 QImage transparentImage = img.copy();
2275 p->drawImage( -transparentImage.width() / 2.0, -transparentImage.height() / 2.0, transparentImage );
2279 p->drawImage( -img.width() / 2.0, -img.height() / 2.0, img );
2284 if ( usePict || !fitsInCache )
2286 p->setOpacity( context.
opacity() );
2290 if ( pct.width() > 1 )
2293 _fixQPictureDPI( p );
2294 p->drawPicture( 0, 0, pct );
2302 double QgsSvgMarkerSymbolLayer::calculateSize(
QgsSymbolRenderContext &context,
bool &hasDataDefinedSize )
const
2304 double scaledSize =
mSize;
2308 if ( hasDataDefinedSize )
2316 if ( hasDataDefinedSize )
2323 if ( hasDataDefinedSize && ok )
2328 scaledSize = std::sqrt( scaledSize );
2341 if ( !hasDataDefinedAspectRatio )
2351 const double defaultHeight =
mSize * scaledAspectRatio;
2352 scaledAspectRatio = defaultHeight / scaledSize;
2355 double scaledHeight = scaledSize * scaledAspectRatio;
2362 if ( hasDataDefinedAspectRatio && ok )
2367 scaledHeight = sqrt( scaledHeight );
2374 scaledAspectRatio = scaledHeight / scaledSize;
2376 return scaledAspectRatio;
2379 void QgsSvgMarkerSymbolLayer::calculateOffsetAndRotation(
QgsSymbolRenderContext &context,
double scaledWidth,
double scaledHeight, QPointF &offset,
double &
angle )
const
2384 markerOffset( context, scaledWidth, scaledHeight, offsetX, offsetY );
2385 offset = QPointF( offsetX, offsetY );
2395 if ( hasDataDefinedRotation )
2421 map[QStringLiteral(
"name" )] =
mPath;
2422 map[QStringLiteral(
"size" )] = QString::number(
mSize );
2425 map[QStringLiteral(
"fixedAspectRatio" )] = QString::number(
mFixedAspectRatio );
2426 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
2433 map[QStringLiteral(
"outline_width" )] = QString::number(
mStrokeWidth );
2508 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
2509 element.appendChild( graphicElem );
2519 const double angle = props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toDouble( &ok );
2522 angleFunc = QStringLiteral(
"%1 + %2" ).arg( props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toString() ).arg(
mAngle );
2540 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
2541 if ( graphicElem.isNull() )
2544 QString
path, mimeType;
2551 double scaleFactor = 1.0;
2552 const QString uom = element.attribute( QStringLiteral(
"uom" ) );
2556 if ( mimeType != QLatin1String(
"image/svg+xml" ) )
2564 const double d = angleFunc.toDouble( &ok );
2590 if ( hasDataDefinedSize )
2596 if ( hasDataDefinedSize && ok )
2610 size *= mmMapUnitScaleFactor;
2624 const double offsetX =
offset.x();
2625 const double offsetY =
offset.y();
2627 QPointF outputOffset( offsetX, offsetY );
2677 QSvgRenderer r( svgContent );
2684 QSizeF outSize( r.defaultSize() );
2685 outSize.scale(
size,
size, Qt::KeepAspectRatio );
2691 p.translate( r.defaultSize().width() / 2.0, r.defaultSize().height() / 2.0 );
2693 p.translate( -r.defaultSize().width() / 2.0, -r.defaultSize().height() / 2.0 );
2695 pd.
setShift( shift + QPointF( outputOffset.x(), -outputOffset.y() ) );
2696 pd.
setOutputSize( QRectF( -outSize.width() / 2.0, -outSize.height() / 2.0, outSize.width(), outSize.height() ) );
2705 bool hasDataDefinedSize =
false;
2706 double scaledWidth = calculateSize( context, hasDataDefinedSize );
2708 bool hasDataDefinedAspectRatio =
false;
2709 const double aspectRatio =
calculateAspectRatio( context, scaledWidth, hasDataDefinedAspectRatio );
2716 if (
static_cast< int >( scaledWidth ) < 1 || 10000.0 < scaledWidth )
2721 QPointF outputOffset;
2723 calculateOffsetAndRotation( context, scaledWidth, scaledHeight, outputOffset,
angle );
2762 scaledHeight = svgViewbox.isValid() ? scaledWidth * svgViewbox.height() / svgViewbox.width() : scaledWidth;
2766 QTransform transform;
2768 transform.translate( point.x() + outputOffset.x(), point.y() + outputOffset.y() );
2771 transform.rotate(
angle );
2776 QRectF symbolBounds = transform.mapRect( QRectF( -scaledWidth / 2.0,
2777 -scaledHeight / 2.0,
2785 return symbolBounds;
2809 if ( props.contains( QStringLiteral(
"imageFile" ) ) )
2810 path = props[QStringLiteral(
"imageFile" )].toString();
2811 if ( props.contains( QStringLiteral(
"size" ) ) )
2812 size = props[QStringLiteral(
"size" )].toDouble();
2813 if ( props.contains( QStringLiteral(
"angle" ) ) )
2814 angle = props[QStringLiteral(
"angle" )].toDouble();
2815 if ( props.contains( QStringLiteral(
"scale_method" ) ) )
2818 std::unique_ptr< QgsRasterMarkerSymbolLayer > m = std::make_unique< QgsRasterMarkerSymbolLayer >(
path,
size,
angle,
scaleMethod );
2819 m->setCommonProperties( props );
2825 if (
properties.contains( QStringLiteral(
"alpha" ) ) )
2830 if (
properties.contains( QStringLiteral(
"size_unit" ) ) )
2832 if (
properties.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
2834 if (
properties.contains( QStringLiteral(
"fixedAspectRatio" ) ) )
2837 if (
properties.contains( QStringLiteral(
"offset" ) ) )
2839 if (
properties.contains( QStringLiteral(
"offset_unit" ) ) )
2841 if (
properties.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
2844 if (
properties.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
2848 if (
properties.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
2859 const QVariantMap::iterator it =
properties.find( QStringLiteral(
"name" ) );
2860 if ( it !=
properties.end() && it.value().type() == QVariant::String )
2878 if ( aPreservedAspectRatio && !par )
2882 else if ( !aPreservedAspectRatio && par )
2901 return QStringLiteral(
"RasterMarker" );
2917 if (
path.isEmpty() )
2921 double height = 0.0;
2923 bool hasDataDefinedSize =
false;
2924 const double scaledSize = calculateSize( context, hasDataDefinedSize );
2926 bool hasDataDefinedAspectRatio =
false;
2927 const double aspectRatio =
calculateAspectRatio( context, scaledSize, hasDataDefinedAspectRatio );
2929 QPointF outputOffset;
2936 if (
size.isEmpty() )
2939 width = ( scaledSize *
static_cast< double >(
size.width() ) ) / 100.0;
2940 height = ( scaledSize *
static_cast< double >(
size.height() ) ) / 100.0;
2943 if (
static_cast< int >( width ) < 1 || 10000.0 < width ||
static_cast< int >( height ) < 1 || 10000.0 < height )
2946 calculateOffsetAndRotation( context, width, height, outputOffset,
angle );
2956 if ( !
size.isNull() &&
size.isValid() &&
size.width() > 0 )
2958 height = width * (
static_cast< double >(
size.height() ) /
static_cast< double >(
size.width() ) );
2963 if (
static_cast< int >( width ) < 1 || 10000.0 < width )
2966 calculateOffsetAndRotation( context, scaledSize, scaledSize * ( height / width ), outputOffset,
angle );
2970 p->translate( point + outputOffset );
2985 if ( !img.isNull() )
2992 p->drawImage( -img.width() / 2.0, -img.height() / 2.0, img );
2998 bool cached =
false;
3002 double QgsRasterMarkerSymbolLayer::calculateSize(
QgsSymbolRenderContext &context,
bool &hasDataDefinedSize )
const
3004 double scaledSize =
mSize;
3008 if ( hasDataDefinedSize )
3016 if ( hasDataDefinedSize )
3023 if ( hasDataDefinedSize && ok )
3028 scaledSize = std::sqrt( scaledSize );
3041 if ( !hasDataDefinedAspectRatio )
3051 const double defaultHeight =
mSize * scaledAspectRatio;
3052 scaledAspectRatio = defaultHeight / scaledSize;
3055 double scaledHeight = scaledSize * scaledAspectRatio;
3062 if ( hasDataDefinedAspectRatio && ok )
3067 scaledHeight = sqrt( scaledHeight );
3074 scaledAspectRatio = scaledHeight / scaledSize;
3076 return scaledAspectRatio;
3079 void QgsRasterMarkerSymbolLayer::calculateOffsetAndRotation(
QgsSymbolRenderContext &context,
double scaledWidth,
double scaledHeight, QPointF &offset,
double &
angle )
const
3084 markerOffset( context, scaledWidth, scaledHeight, offsetX, offsetY );
3085 offset = QPointF( offsetX, offsetY );
3095 if ( hasDataDefinedRotation )
3116 map[QStringLiteral(
"imageFile" )] =
mPath;
3117 map[QStringLiteral(
"size" )] = QString::number(
mSize );
3120 map[QStringLiteral(
"fixedAspectRatio" )] = QString::number(
mFixedAspectRatio );
3121 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
3122 map[QStringLiteral(
"alpha" )] = QString::number(
mOpacity );
3134 std::unique_ptr< QgsRasterMarkerSymbolLayer > m = std::make_unique< QgsRasterMarkerSymbolLayer >(
mPath,
mSize,
mAngle );
3178 bool hasDataDefinedSize =
false;
3179 const double scaledSize = calculateSize( context, hasDataDefinedSize );
3181 bool hasDataDefinedAspectRatio =
false;
3182 const double aspectRatio =
calculateAspectRatio( context, scaledSize, hasDataDefinedAspectRatio );
3186 if (
static_cast< int >( scaledSize ) < 1 || 10000.0 < scaledSize )
3191 QPointF outputOffset;
3193 calculateOffsetAndRotation( context, scaledSize, scaledSize * ( height / width ), outputOffset,
angle );
3195 QTransform transform;
3198 transform.translate( point.x() + outputOffset.x(), point.y() + outputOffset.y() );
3201 transform.rotate(
angle );
3203 QRectF symbolBounds = transform.mapRect( QRectF( -width / 2.0,
3208 return symbolBounds;
3220 mOrigSize = pointSize;
3240 if ( props.contains( QStringLiteral(
"font" ) ) )
3241 fontFamily = props[QStringLiteral(
"font" )].toString();
3242 if ( props.contains( QStringLiteral(
"chr" ) ) && props[QStringLiteral(
"chr" )].toString().length() > 0 )
3243 string = props[QStringLiteral(
"chr" )].toString();
3244 if ( props.contains( QStringLiteral(
"size" ) ) )
3245 pointSize = props[QStringLiteral(
"size" )].toDouble();
3246 if ( props.contains( QStringLiteral(
"color" ) ) )
3248 if ( props.contains( QStringLiteral(
"angle" ) ) )
3249 angle = props[QStringLiteral(
"angle" )].toDouble();
3253 if ( props.contains( QStringLiteral(
"font_style" ) ) )
3254 m->
setFontStyle( props[QStringLiteral(
"font_style" )].toString() );
3255 if ( props.contains( QStringLiteral(
"outline_color" ) ) )
3257 if ( props.contains( QStringLiteral(
"outline_width" ) ) )
3258 m->
setStrokeWidth( props[QStringLiteral(
"outline_width" )].toDouble() );
3259 if ( props.contains( QStringLiteral(
"offset" ) ) )
3261 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
3263 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
3265 if ( props.contains( QStringLiteral(
"size_unit" ) ) )
3267 if ( props.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
3269 if ( props.contains( QStringLiteral(
"outline_width_unit" ) ) )
3271 if ( props.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
3273 if ( props.contains( QStringLiteral(
"joinstyle" ) ) )
3275 if ( props.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
3277 if ( props.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
3287 return QStringLiteral(
"FontMarker" );
3292 QColor brushColor =
mColor;
3293 QColor penColor = mStrokeColor;
3295 brushColor.setAlphaF(
mColor.alphaF() * context.
opacity() );
3296 penColor.setAlphaF( mStrokeColor.alphaF() * context.
opacity() );
3298 mBrush = QBrush( brushColor );
3299 mPen = QPen( penColor );
3300 mPen.setJoinStyle( mPenJoinStyle );
3303 mFont = QFont( mFontFamily );
3304 if ( !mFontStyle.isEmpty() )
3312 if ( mNonZeroFontSize && sizePixels > MAX_FONT_CHARACTER_SIZE_IN_PIXELS )
3317 mFontSizeScale = sizePixels / MAX_FONT_CHARACTER_SIZE_IN_PIXELS;
3318 sizePixels = MAX_FONT_CHARACTER_SIZE_IN_PIXELS;
3321 mFontSizeScale = 1.0;
3325 mFont.setPixelSize( std::max( 2,
static_cast< int >( std::round( sizePixels ) ) ) );
3326 mFontMetrics.reset(
new QFontMetrics( mFont ) );
3327 mChrWidth = mFontMetrics->horizontalAdvance( mString );
3328 mChrOffset = QPointF( mChrWidth / 2.0, -mFontMetrics->ascent() / 2.0 );
3335 if ( mUseCachedPath )
3337 QPointF chrOffset = mChrOffset;
3339 const QString charToRender = characterToRender( context, chrOffset, chrWidth );
3340 mCachedPath = QPainterPath();
3341 mCachedPath.addText( -chrOffset.x(), -chrOffset.y(), mFont, charToRender );
3350 QString QgsFontMarkerSymbolLayer::characterToRender(
QgsSymbolRenderContext &context, QPointF &charOffset,
double &charWidth )
3352 charOffset = mChrOffset;
3353 QString stringToRender = mString;
3358 if ( stringToRender != mString )
3360 charWidth = mFontMetrics->horizontalAdvance( stringToRender );
3361 charOffset = QPointF( charWidth / 2.0, -mFontMetrics->ascent() / 2.0 );
3364 return stringToRender;
3369 bool &hasDataDefinedRotation,
3371 double &
angle )
const
3376 markerOffset( context, scaledSize, scaledSize, offsetX, offsetY );
3377 offset = QPointF( offsetX, offsetY );
3393 if ( hasDataDefinedRotation )
3417 double scaledSize =
mSize;
3421 if ( hasDataDefinedSize )
3427 if ( hasDataDefinedSize && ok )
3432 scaledSize = std::sqrt( scaledSize );
3444 if ( !p || !mNonZeroFontSize )
3447 QTransform transform;
3450 QColor brushColor =
mColor;
3459 brushColor.setAlphaF( brushColor.alphaF() * context.
opacity() );
3461 mBrush.setColor( brushColor );
3463 QColor penColor = mStrokeColor;
3469 penColor.setAlphaF( penColor.alphaF() * context.
opacity() );
3493 p->setBrush( mBrush );
3496 mPen.setColor( penColor );
3497 mPen.setWidthF( penWidth );
3502 p->setPen( Qt::NoPen );
3509 mFont.setFamily( ok ?
fontFamily : mFontFamily );
3519 mFontMetrics.reset(
new QFontMetrics( mFont ) );
3522 QPointF chrOffset = mChrOffset;
3524 const QString charToRender = characterToRender( context, chrOffset, chrWidth );
3526 const double sizeToRender = calculateSize( context );
3528 bool hasDataDefinedRotation =
false;
3531 calculateOffsetAndRotation( context, sizeToRender, hasDataDefinedRotation,
offset,
angle );
3533 p->translate( point.x() +
offset.x(), point.y() +
offset.y() );
3536 transform.rotate(
angle );
3540 const double s = sizeToRender / mOrigSize;
3541 transform.scale( s, s );
3545 transform.scale( mFontSizeScale, mFontSizeScale );
3547 if ( mUseCachedPath )
3549 p->drawPath( transform.map( mCachedPath ) );
3554 path.addText( -chrOffset.x(), -chrOffset.y(), mFont, charToRender );
3555 p->drawPath( transform.map( path ) );
3562 props[QStringLiteral(
"font" )] = mFontFamily;
3563 props[QStringLiteral(
"font_style" )] = mFontStyle;
3564 props[QStringLiteral(
"chr" )] = mString;
3565 props[QStringLiteral(
"size" )] = QString::number(
mSize );
3570 props[QStringLiteral(
"outline_width" )] = QString::number( mStrokeWidth );
3574 props[QStringLiteral(
"angle" )] = QString::number(
mAngle );
3607 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
3608 element.appendChild( graphicElem );
3610 const QString fontPath = QStringLiteral(
"ttf://%1" ).arg( mFontFamily );
3611 int markIndex = !mString.isEmpty() ? mString.at( 0 ).unicode() : 0;
3618 const double angle = props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toDouble( &ok );
3621 angleFunc = QStringLiteral(
"%1 + %2" ).arg( props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toString() ).arg(
mAngle );
3644 mStrokeWidthUnit = unit;
3649 QPointF chrOffset = mChrOffset;
3650 double chrWidth = mChrWidth;
3652 ( void )characterToRender( context, chrOffset, chrWidth );
3654 if ( !mFontMetrics )
3655 mFontMetrics.reset(
new QFontMetrics( mFont ) );
3657 double scaledSize = calculateSize( context );
3660 chrWidth *= scaledSize / mOrigSize;
3662 chrWidth *= mFontSizeScale;
3664 bool hasDataDefinedRotation =
false;
3667 calculateOffsetAndRotation( context, scaledSize, hasDataDefinedRotation,
offset,
angle );
3670 QTransform transform;
3673 transform.translate( point.x() +
offset.x(), point.y() +
offset.y() );
3676 transform.rotate(
angle );
3678 QRectF symbolBounds = transform.mapRect( QRectF( -chrWidth / 2.0,
3682 return symbolBounds;
3689 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
3690 if ( graphicElem.isNull() )
3693 QString name, format;
3701 if ( !name.startsWith( QLatin1String(
"ttf://" ) ) || format != QLatin1String(
"ttf" ) )
3711 const double d = angleFunc.toDouble( &ok );
3719 double scaleFactor = 1.0;
3720 const QString uom = element.attribute( QStringLiteral(
"uom" ) );
3744 QMap<QString, QgsProperty>::iterator it =
mParameters.begin();
3756 QMap<QString, QgsProperty>::const_iterator it =
mParameters.constBegin();
3759 attrs.unite( it.value().referencedFields( context.
expressionContext(),
true ) );
3783 if (
properties.contains( QStringLiteral(
"imageFile" ) ) )
3785 if (
properties.contains( QStringLiteral(
"size" ) ) )
3787 if (
properties.contains( QStringLiteral(
"angle" ) ) )
3790 std::unique_ptr< QgsAnimatedMarkerSymbolLayer > m = std::make_unique< QgsAnimatedMarkerSymbolLayer >(
path,
size,
angle );
3791 m->setFrameRate(
properties.value( QStringLiteral(
"frameRate" ), QStringLiteral(
"10" ) ).toDouble() );
3799 return QStringLiteral(
"AnimatedMarker" );
3805 res.insert( QStringLiteral(
"frameRate" ), mFrameRateFps );
3811 std::unique_ptr< QgsAnimatedMarkerSymbolLayer > m = std::make_unique< QgsAnimatedMarkerSymbolLayer >(
mPath,
mSize,
mAngle );
3812 m->setFrameRate( mFrameRateFps );
3821 mPreparedPaths.clear();
3829 mStaticPath =
false;
3835 if ( !mStaticPath && !mPreparedPaths.contains(
path ) )
3838 mPreparedPaths.insert(
path );
3841 const long long mapFrameNumber = context.
currentFrame();
3843 const double markerAnimationDuration = totalFrameCount / mFrameRateFps;
3845 double animationTimeSeconds = 0;
3846 if ( mapFrameNumber >= 0 && context.
frameRate() > 0 )
3849 animationTimeSeconds = mapFrameNumber / context.
frameRate();
3854 animationTimeSeconds = QDateTime::currentMSecsSinceEpoch() / 1000.0;
3857 const double markerAnimationProgressSeconds = std::fmod( animationTimeSeconds, markerAnimationDuration );
3858 const int movieFrame =
static_cast< int >( std::floor( markerAnimationProgressSeconds * mFrameRateFps ) );
3860 bool cached =
false;
static QList< Qgis::MarkerShape > availableShapes()
Returns a list of all available shape types.
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for data defined symbology.
QgsAnimatedMarkerSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
void setColor(const QColor &c) override
Sets the "representative" color for the symbol layer.
Q_GUI_EXPORT int qt_defaultDpiX()
double defaultAspectRatio() const
Returns the default marker aspect ratio between width and height, 0 if not yet calculated.
double mFixedAspectRatio
The marker fixed aspect ratio.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsFilledMarkerSymbolLayer.
void setSizeUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the symbol's size.
QgsMapUnitScale mapUnitScale() const override
@ RenderSymbolPreview
The render is for a symbol preview only and map based properties may not be available,...
QString layerType() const override
Returns a string that represents this layer type.
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.
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 QString encodeColor(const QColor &color)
void setHorizontalAnchorPoint(HorizontalAnchorPoint h)
Sets the horizontal anchor point for positioning the symbol.
VerticalAnchorPoint
Symbol vertical anchor points.
void renderPoint(QPointF point, QgsSymbolRenderContext &context) override
Renders a marker at the specified point.
@ ArrowHead
Right facing arrow head (unfilled, lines only)
void setPainterFlagsUsingContext(QPainter *painter=nullptr) const
Sets relevant flags on a destination painter, using the flags and settings currently defined for the ...
@ QuarterArc
A line-only one quarter arc (since QGIS 3.20)
@ SemiCircle
Semi circle (top half)
Filled marker symbol layer, consisting of a shape which is rendered using a QgsFillSymbol....
const QgsMapToPixel & mapToPixel() const
Returns the context's map to pixel transform, which transforms between map coordinates and device coo...
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
void setStrokeWidthMapUnitScale(const QgsMapUnitScale &scale)
Sets the map scale for the width of the marker's stroke.
QSize originalSize(const QString &path, bool blocking=false) const
Returns the original size (in pixels) of the image at the specified path.
@ DiagonalHalfSquare
Diagonal half square (bottom left half)
double size() const
Returns the symbol size.
virtual void setColor(const QColor &color)
Sets the "representative" color for the symbol layer.
#define DEFAULT_SIMPLEMARKER_ANGLE
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...
double opacity() const
Returns the marker opacity.
RenderUnit
Rendering size units.
Qt::PenStyle strokeStyle() const
Returns the marker's stroke style (e.g., solid, dashed, etc)
double mDefaultAspectRatio
The marker default aspect ratio.
void renderPoint(QPointF point, QgsSymbolRenderContext &context) override
Renders a marker at the specified point.
Exports QGIS layers to the DXF format.
QgsMapUnitScale mSizeMapUnitScale
Marker size map unit scale.
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 setStrokeWidth(double width)
Set's the marker's stroke width.
Qt::PenJoinStyle penJoinStyle() const
Returns the marker's stroke join style (e.g., miter, bevel, etc).
void setOutputUnit(QgsUnitTypes::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QgsExpressionContext & expressionContext()
Gets the expression context.
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
double mapUnitsPerPixel() const
Returns the current map units per pixel.
static bool externalGraphicFromSld(QDomElement &element, QString &path, QString &mime, QColor &color, double &size)
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
bool shapeToPolygon(Qgis::MarkerShape shape, QPolygonF &polygon) const
Creates a polygon representing the specified shape.
#define DEFAULT_SIMPLEMARKER_NAME
The class is used as a container of context for various read/write operations on other objects.
static bool wellKnownMarkerFromSld(QDomElement &element, QString &name, QColor &color, QColor &strokeColor, Qt::PenStyle &strokeStyle, double &strokeWidth, double &size)
QgsMapUnitScale mapUnitScale() const override
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
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.
@ CrossFill
Solid filled cross.
static QString encodeMapUnitScale(const QgsMapUnitScale &mapUnitScale)
Point geometry type, with support for z-dimension and m-values.
void writePolygon(const QgsRingSequence &polygon, const QString &layer, const QString &hatchPattern, const QColor &color)
Draw dxf filled polygon (HATCH)
#define QgsDebugMsgLevel(str, level)
const QgsFeature * feature() const
Returns the current feature being rendered.
void setDrawingSize(QSizeF size)
virtual void prepareExpressions(const QgsSymbolRenderContext &context)
Prepares all data defined property expressions for evaluation.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates an animated marker symbol layer from a string map of properties.
void setOutputUnit(QgsUnitTypes::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
Qt::PenJoinStyle mPenJoinStyle
Stroke pen join style.
static bool externalMarkerFromSld(QDomElement &element, QString &path, QString &format, int &markIndex, QColor &color, double &size)
@ ArrowHeadFilled
Right facing filled arrow head.
Qgis::MarkerShape mShape
Symbol shape.
@ PropertyFontFamily
Font family.
@ AsteriskFill
A filled asterisk shape (since QGIS 3.18)
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.
QImage mSelCache
Cached image of selected marker, if using cached version.
@ Cross2
Rotated cross (lines only), 'x' shape.
@ PropertyFillColor
Fill color.
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
#define DEFAULT_FONTMARKER_ANGLE
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
void setAngle(double angle)
Sets the rotation angle for the marker.
qreal opacity() const
Returns the opacity for the symbol.
static QString encodePenCapStyle(Qt::PenCapStyle style)
double updateDefaultAspectRatio()
Calculates the default marker aspect ratio between width and height.
void setPath(const QString &path)
Set the marker SVG path.
virtual bool hasDataDefinedProperties() const
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
Qgis::RenderContextFlags flags() const
Returns combination of flags used for rendering.
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.
@ RenderPercentage
Percentage of another measurement (e.g., canvas size, feature size)
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
Contains information about the context of a rendering operation.
#define DEFAULT_RASTERMARKER_SIZE
static void multiplyImageOpacity(QImage *image, qreal opacity)
Multiplies opacity of image pixel values with a (global) transparency value.
static const bool SELECTION_IS_OPAQUE
Whether styles for selected features ignore symbol alpha.
void setColor(const QColor &color) override
Sets the "representative" color for the symbol layer.
void setParameters(const QMap< QString, QgsProperty > ¶meters)
Sets the dynamic SVG parameters.
void setStrokeStyle(Qt::PenStyle strokeStyle)
Sets the marker's stroke style (e.g., solid, dashed, etc)
@ RenderMillimeters
Millimeters.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
#define DEFAULT_FONTMARKER_FONT
Abstract base class for marker symbol layers.
QString ogrFeatureStyle(double mmScaleFactor, double mapUnitScaleFactor) const override
void setOpacity(double opacity)
Set the marker opacity.
void copyCommonProperties(QgsRasterMarkerSymbolLayer *other) const
Copies common properties to another layer.
@ PropertyCapStyle
Line cap style.
void setStrokeColor(const QColor &color) override
Sets the stroke color for the symbol layer.
static QString encodePenStyle(Qt::PenStyle style)
long long currentFrame() const
Returns the current frame number of the map (in frames per second), for maps which are part of an ani...
QgsMapUnitScale mapUnitScale() const override
#define DEFAULT_SIMPLEMARKER_JOINSTYLE
Abstract base class for all rendered symbols.
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
QgsSimpleMarkerSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
static QString svgSymbolPathToName(const QString &path, const QgsPathResolver &pathResolver)
Determines an SVG symbol's name from its path.
QgsUnitTypes::RenderUnit mSizeUnit
Marker size unit.
double scaleFactor() const
Returns the scaling factor for the render to convert painter units to physical sizes.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
@ PropertyStrokeColor
Stroke color.
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 setMapUnitScale(const QgsMapUnitScale &scale) override
Animated marker symbol layer class.
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
QColor color() const override
Returns the "representative" color of the symbol layer.
static QColor decodeColor(const QString &str)
QgsRasterMarkerSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
static QgsSymbolLayer * createFromSld(QDomElement &element)
VerticalAnchorPoint mVerticalAnchorPoint
Vertical anchor point.
static double mapUnitScaleFactor(double scale, QgsUnitTypes::RenderUnit symbolUnits, QgsUnitTypes::DistanceUnit mapUnits, double mapUnitsPerPixel=1.0)
Returns scale factor for conversion to map units.
@ ScaleDiameter
Calculate scale by the diameter.
double frameRate() const
Returns the frame rate of the map, for maps which are part of an animation.
void setFontStyle(const QString &style)
Sets the font style for the font which will be used to render the point.
static void wellKnownMarkerToSld(QDomDocument &doc, QDomElement &element, const QString &name, const QColor &color, const QColor &strokeColor, Qt::PenStyle strokeStyle, double strokeWidth=-1, double size=-1)
QgsFontMarkerSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
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.
void writeSldMarker(QDomDocument &doc, QDomElement &element, const QVariantMap &props) const override
Writes the symbol layer definition as a SLD XML element.
void setStrokeWidthUnit(QgsUnitTypes::RenderUnit u)
Sets the unit for the width of the marker's stroke.
void setOutputUnit(QgsUnitTypes::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QBrush mSelBrush
QBrush to use as fill of selected symbols.
QMap< QString, QgsProperty > mParameters
void setStrokeWidthUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the stroke width.
ScaleMethod
Scale methods.
@ PropertyFontStyle
Font style.
QgsUnitTypes::RenderUnit mOffsetUnit
Offset units.
int totalFrameCount(const QString &path, bool blocking=false)
Returns the total frame count of the image at the specified path.
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
bool selected() const
Returns true if symbols should be rendered using the selected symbol coloring and style.
static void createDisplacementElement(QDomDocument &doc, QDomElement &element, QPointF offset)
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.
Q_GUI_EXPORT int qt_defaultDpiY()
static Q_INVOKABLE QgsUnitTypes::RenderUnit decodeRenderUnit(const QString &string, bool *ok=nullptr)
Decodes a render unit from a string.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
void setFixedAspectRatio(double ratio)
Set the marker aspect ratio between width and height to be used in rendering, if the value set is low...
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...
QColor color() const override
Returns the "representative" color of the symbol layer.
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
HorizontalAnchorPoint
Symbol horizontal anchor points.
static QString encodeScaleMethod(Qgis::ScaleMethod scaleMethod)
Encodes a symbol scale method to a string.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
double strokeWidth() const
void setOutputUnit(QgsUnitTypes::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
double updateDefaultAspectRatio()
Calculates the default marker aspect ratio between width and height.
static QPointF toPoint(const QVariant &value, bool *ok=nullptr)
Converts a value to a point.
void setStrokeWidthUnit(QgsUnitTypes::RenderUnit unit)
Sets the stroke width unit.
QRectF bounds(QPointF point, QgsSymbolRenderContext &context) override
Returns the approximate bounding box of the marker symbol layer, taking into account any data defined...
bool prepareMarkerShape(Qgis::MarkerShape shape)
Prepares the layer for drawing the specified shape (QPolygonF version)
void setStrokeColor(const QColor &c) override
Sets the stroke color for the symbol layer.
void markerOffset(QgsSymbolRenderContext &context, double &offsetX, double &offsetY) const
Calculates the required marker offset, including both the symbol offset and any displacement required...
Abstract base class for simple marker symbol layers. Handles creation of the symbol shapes but leaves...
@ ThirdArc
A line-only one third arc (since QGIS 3.20)
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsSimpleMarkerSymbolLayer.
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.
QColor strokeColor() const override
Returns the stroke color for the symbol layer.
QBrush mBrush
QBrush corresponding to marker's fill style.
Qgis::ScaleMethod scaleMethod() const
Returns the method to use for scaling the marker's size.
#define DEFAULT_SVGMARKER_ANGLE
@ PropertyOffset
Symbol offset.
@ PropertyCharacter
Character, eg for font marker symbol layers.
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.
bool forceVectorOutput() const
Returns true if rendering operations should use vector operations instead of any faster raster shortc...
QgsUnitTypes::DistanceUnit mapUnits() const
Retrieve map units.
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.
A paint device for drawing into dxf files.
QColor fillColor() const override
Returns the fill color for the symbol layer.
~QgsRasterMarkerSymbolLayer() override
void setMapUnitScale(const QgsMapUnitScale &scale) override
void prepareExpressions(const QgsSymbolRenderContext &context) override
Prepares all data defined property expressions for evaluation.
static Q_INVOKABLE QString encodeUnit(QgsUnitTypes::DistanceUnit unit)
Encodes a distance unit to a string.
QgsUnitTypes::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
static const int MAXIMUM_CACHE_WIDTH
Maximum width/height of cache image.
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
bool preservedAspectRatio() const
Returns the preserved aspect ratio value, true if fixed aspect ratio has been lower or equal to 0.
QColor color() const override
Returns the "representative" color of the symbol layer.
QgsMapUnitScale mStrokeWidthMapUnitScale
QgsFields fields() const
Fields of the layer.
QString layerType() const override
Returns a string that represents this layer type.
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 setLayer(const QString &layer)
Qgis::SymbolType type() const
Returns the symbol's type.
void setPenCapStyle(Qt::PenCapStyle style)
Sets the marker's stroke cap style (e.g., flat, round, etc).
static Qgis::ScaleMethod decodeScaleMethod(const QString &str)
Decodes a symbol scale method from a string.
QColor fillColor() const override
Returns the fill color for the symbol layer.
void setStrokeWidth(double w)
static QgsSymbolLayer * createFromSld(QDomElement &element)
Creates a new QgsFontMarkerSymbolLayer from an SLD XML element.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
static Qgis::MarkerShape decodeShape(const QString &name, bool *ok=nullptr)
Attempts to decode a string representation of a shape name to the corresponding shape.
void setFlag(Qgis::RenderContextFlag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected)
QString layerType() const override
Returns a string that represents this layer type.
double mapRotation() const
Returns the current map rotation in degrees (clockwise).
bool setPreservedAspectRatio(bool par)
Set preserved the marker aspect ratio between width and height.
QString path() const
Returns the marker SVG path.
static QString translateNamedStyle(const QString &namedStyle)
Returns the localized named style of a font, if such a translation is available.
#define DEFAULT_FONTMARKER_SIZE
bool writeDxf(QgsDxfExport &e, double mmMapUnitScaleFactor, const QString &layerName, QgsSymbolRenderContext &context, QPointF shift=QPointF(0.0, 0.0)) const override
write as DXF
Simple marker symbol layer, consisting of a rendered shape with solid fill color and an stroke.
void writeSldMarker(QDomDocument &doc, QDomElement &element, const QVariantMap &props) const override
Writes the symbol layer definition as a SLD XML element.
QPolygonF mPolygon
Polygon of points in shape. If polygon is empty then shape is using mPath.
#define DEFAULT_FONTMARKER_CHR
QgsSymbol * subSymbol() override
Returns the symbol's sub symbol, if present.
@ PropertySize
Symbol size.
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.
void copyPaintEffect(QgsSymbolLayer *destLayer) const
Copies paint effect of this layer to another symbol layer.
static QPointF decodePoint(const QString &string)
Decodes a QSizeF from a string.
@ DynamicRotation
Rotation of symbol may be changed during rendering and symbol should not be cached.
@ PropertyStrokeStyle
Stroke style (eg solid, dashed)
QgsUnitTypes::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
static double rescaleUom(double size, QgsUnitTypes::RenderUnit unit, const QVariantMap &props)
Rescales the given size based on the uomScale found in the props, if any is found,...
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.
double calculateAspectRatio(QgsSymbolRenderContext &context, double scaledSize, bool &hasDataDefinedAspectRatio) const
Calculates the marker aspect ratio between width and height.
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 setPath(const QString &path)
Set the marker raster image path.
#define DEFAULT_SIMPLEMARKER_BORDERCOLOR
#define DEFAULT_FONTMARKER_BORDERCOLOR
bool prepareCache(QgsSymbolRenderContext &context)
Prepares cache image.
double strokeWidth() const
Returns 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 writeCircle(const QString &layer, const QColor &color, const QgsPoint &pt, double radius, const QString &lineStyleName, double width)
Write circle (as polyline)
void setPenJoinStyle(Qt::PenJoinStyle style)
Sets the stroke join style.
Raster marker symbol layer class.
static bool fontFamilyMatchOnSystem(const QString &family, QString *chosen=nullptr, bool *match=nullptr)
Check whether font family is on system.
QColor mStrokeColor
Stroke color.
void renderPoint(QPointF point, QgsSymbolRenderContext &context) override
Renders a marker at the specified point.
QgsUnitTypes::RenderUnit mStrokeWidthUnit
void restoreOldDataDefinedProperties(const QVariantMap &stringMap)
Restores older data defined properties from string map.
@ PropertyName
Name, eg shape name for simple markers.
void setOffset(QPointF offset)
Sets the marker's offset, which is the horizontal and vertical displacement which the rendered marker...
QgsSvgMarkerSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
Struct for storing maximum and minimum scales for measurements in map units.
@ SquareWithCorners
A square with diagonal corners (since QGIS 3.18)
Scoped object for saving and restoring a QPainter object's state.
void setStrokeWidth(double w)
Sets the width of the marker's stroke.
QgsPropertyCollection mDataDefinedProperties
@ PropertyStrokeWidth
Stroke width.
QRectF bounds(QPointF point, QgsSymbolRenderContext &context) override
Returns the approximate bounding box of the marker symbol layer, taking into account any data defined...
static QgsFillSymbol * createSimple(const QVariantMap &properties)
Create a fill symbol with one symbol layer: SimpleFill with specified properties.
QVector< QgsPointSequence > QgsRingSequence
QString path() const
Returns the marker raster image path.
void setOffsetUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the symbol's offset.
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.
Qt::PenStyle mStrokeStyle
Stroke style.
static QString encodePoint(QPointF point)
Encodes a QPointF to a string.
@ QuarterCircle
Quarter circle (top left quarter)
static QgsSvgCache * svgCache()
Returns the application's SVG cache, used for caching SVG images and handling parameter replacement w...
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.
virtual QSet< QString > usedAttributes(const QgsRenderContext &context) const
Returns the set of attributes referenced by the layer.
@ HalfSquare
Half square (left half)
void setStrokeWidthMapUnitScale(const QgsMapUnitScale &scale)
QColor strokeColor() const override
Returns the marker's stroke color.
static QgsUnitTypes::RenderUnit decodeSldUom(const QString &str, double *scaleFactor=nullptr)
Decodes a SLD unit of measure string to a render unit.
void writeSldMarker(QDomDocument &doc, QDomElement &element, const QVariantMap &props) const override
Writes the symbol layer definition as a SLD XML element.
Qgis::MarkerShape shape() const
Returns the shape for the rendered marker symbol.
double convertToPainterUnits(double size, QgsUnitTypes::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale(), Qgis::RenderSubcomponentProperty property=Qgis::RenderSubcomponentProperty::Generic) const
Converts a size from the specified units to painter units (pixels).
static Qt::PenCapStyle decodePenCapStyle(const QString &str)
@ LeftHalfTriangle
Left half of triangle.
QPen mSelPen
QPen to use as stroke of selected symbols.
QImage fetchImage(QgsRenderContext &context, const QString &path, QSize size, bool preserveAspectRatio, double opacity) const override
Fetches the image to render.
QgsMapUnitScale mapUnitScale() const override
Qgis::ScaleMethod mScaleMethod
Marker size scaling method.
QColor selectionColor() const
Returns the color to use when rendering selected features.
static QgsSymbolLayer * createFromSld(QDomElement &element)
Creates a new QgsSimpleMarkerSymbolLayer from an SLD XML element.
double calculateAspectRatio(QgsSymbolRenderContext &context, double scaledSize, bool &hasDataDefinedAspectRatio) const
Calculates the marker aspect ratio between width and height.
void setOffsetMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the symbol's offset.
void setOutputUnit(QgsUnitTypes::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
@ RenderBlocking
Render and load remote sources in the same thread to ensure rendering remote sources (svg and images)...
QMap< QString, QString > QgsStringMap
void setMapUnitScale(const QgsMapUnitScale &scale) override
QPointF mOffset
Marker offset.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsFontMarkerSymbolLayer from a property map (see properties())
QString fontStyle() const
Returns the font style for the associated font which will be used to render the point.
void renderPoint(QPointF point, QgsSymbolRenderContext &context) override
Renders a marker at the specified point.
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer's subsymbol. takes ownership of the passed symbol.
QString layerType() const override
Returns a string that represents this layer type.
HorizontalAnchorPoint mHorizontalAnchorPoint
Horizontal anchor point.
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
void setFillColor(const QColor &color) override
Sets the fill color for the symbol layer.
~QgsAnimatedMarkerSymbolLayer() override
void setFixedAspectRatio(double ratio)
Set the marker aspect ratio between width and height to be used in rendering, if the value set is low...
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.
QgsFilledMarkerSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
bool prepareMarkerPath(Qgis::MarkerShape symbol)
Prepares the layer for drawing the specified shape (QPainterPath version)
QVector< QgsPoint > QgsPointSequence
QVariant value(int key, const QgsExpressionContext &context, const QVariant &defaultValue=QVariant()) const override
Returns the calculated value of the property with the specified key from within the collection.
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
QPainterPath mPath
Painter path representing shape. If mPolygon is empty then the shape is stored in mPath.
Perform transforms between map coordinates and device coordinates.
void writeFilledCircle(const QString &layer, const QColor &color, const QgsPoint &pt, double radius)
Write filled circle (as hatch)
bool hasDataDefinedProperties() const override
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
#define DEFAULT_SVGMARKER_SIZE
void setStrokeColor(const QColor &color) override
Sets the marker's stroke color.
bool hasGeometry() const
Returns true if the feature has an associated geometry.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
QgsUnitTypes::RenderUnit mStrokeWidthUnit
Stroke width units.
QString layerType() const override
Returns a string that represents this layer type.
static QString svgSymbolNameToPath(const QString &name, const QgsPathResolver &pathResolver)
Determines an SVG symbol's path from its name.
double mLineAngle
Line rotation angle (see setLineAngle() for details)
~QgsSvgMarkerSymbolLayer() override
#define DEFAULT_SCALE_METHOD
void renderPoint(QPointF point, QgsSymbolRenderContext &context) override
Renders a marker at the specified point.
static bool rotationFromSldElement(QDomElement &element, QString &rotationFunc)
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
static QString encodeShape(Qgis::MarkerShape shape)
Encodes a shape to its string representation.
@ PropertyAngle
Symbol angle.
A fill symbol type, for rendering Polygon and MultiPolygon geometries.
@ ScaleArea
Calculate scale by the area.
@ RenderMetersInMapUnits
Meters value as Map units.
bool preservedAspectRatio() const
Returns the preserved aspect ratio value, true if fixed aspect ratio has been lower or equal to 0.
const QgsPathResolver & pathResolver() const
Returns the path resolver for conversion between relative and absolute paths during rendering operati...
@ RenderUnknownUnit
Mixed or unknown units.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
@ HalfArc
A line-only half arc (since QGIS 3.20)
double mOpacity
The marker default opacity.
QMap< QString, QgsProperty > parameters() const
Returns the dynamic SVG parameters.
static Qt::PenJoinStyle decodePenJoinStyle(const QString &str)
@ EquilateralTriangle
Equilateral triangle.
bool mUsingCache
true if using cached images of markers for drawing.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
@ QuarterSquare
Quarter square (top left quarter)
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
static void createRotationElement(QDomDocument &doc, QDomElement &element, const QString &rotationFunc)
void setCommonProperties(const QVariantMap &properties)
Sets common class properties from a properties map.
static QPointF _rotatedOffset(QPointF offset, double angle)
Adjusts a marker offset to account for rotation.
QPointF offset() const
Returns the marker's offset, which is the horizontal and vertical displacement which the rendered mar...
void setOutputSize(const QRectF &r)
void setSizeMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the symbol's size.
void setVerticalAnchorPoint(VerticalAnchorPoint v)
Sets the vertical anchor point for positioning the symbol.
QImage mCache
Cached image of marker, if using cached version.
~QgsSimpleMarkerSymbolLayerBase() override
void calculateOffsetAndRotation(QgsSymbolRenderContext &context, double scaledSize, bool &hasDataDefinedRotation, QPointF &offset, double &angle) const
Calculates the marker offset and rotation.
#define DEFAULT_FONTMARKER_JOINSTYLE
double mAngle
Marker rotation angle, in degrees clockwise from north.
Qt::PenCapStyle mPenCapStyle
Stroke pen cap style.
virtual QColor color() const
Returns the "representative" color of the symbol layer.
~QgsSimpleMarkerSymbolLayer() override
static QString encodePenJoinStyle(Qt::PenJoinStyle style)
void prepareAnimation(const QString &path)
Prepares for optimized retrieval of frames for the animation at the given path.
Qgis::SymbolRenderHints renderHints() const
Returns the rendering hint flags for the symbol.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
@ PropertyOpacity
Opacity.
QgsRenderContext & renderContext()
Returns a reference to the context's render context.
double symbologyScale() const
Returns the reference scale for output.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a raster marker symbol layer from a string map of properties.
static double estimateMaxSymbolBleed(QgsSymbol *symbol, const QgsRenderContext &context)
Returns the maximum estimated bleed for the symbol.
void setStrokeWidthMapUnitScale(const QgsMapUnitScale &scale)
Sets the stroke width map unit scale.
void setShift(QPointF shift)
@ RightHalfTriangle
Right half of triangle.
@ Octagon
Octagon (since QGIS 3.18)
void clipValueToMapUnitScale(double &value, const QgsMapUnitScale &scale, double pixelToMMFactor) const
Clips value to scale minimum/maximum.
@ PropertyHeight
Symbol height.
static void parametricSvgToSld(QDomDocument &doc, QDomElement &graphicElem, const QString &path, const QColor &fillColor, double size, const QColor &strokeColor, double strokeWidth)
Encodes a reference to a parametric SVG into SLD, as a succession of parametric SVG using URL paramet...
MarkerShape
Marker shapes.
@ RenderingSubSymbol
Set whenever a sub-symbol of a parent symbol is currently being rendered. Can be used during symbol a...
QPainter * painter()
Returns the destination QPainter for the render operation.
QgsUnitTypes::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
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.
#define DEFAULT_FONTMARKER_COLOR
static Qt::PenStyle decodePenStyle(const QString &str)
#define DEFAULT_SIMPLEMARKER_COLOR
bool writeDxf(QgsDxfExport &e, double mmMapUnitScaleFactor, const QString &layerName, QgsSymbolRenderContext &context, QPointF shift=QPointF(0.0, 0.0)) const override
write as DXF
static void overlayColor(QImage &image, const QColor &color)
Overlays a color onto an image.
virtual QImage fetchImage(QgsRenderContext &context, const QString &path, QSize size, bool preserveAspectRatio, double opacity) const
Fetches the image to render.
double mDefaultAspectRatio
The marker default aspect ratio.
static bool displacementFromSldElement(QDomElement &element, QPointF &offset)
bool isActive(int key) const override
Returns true if the collection contains an active property with the specified key.
static void externalMarkerToSld(QDomDocument &doc, QDomElement &element, const QString &path, const QString &format, int *markIndex=nullptr, const QColor &color=QColor(), double size=-1)
QgsWkbTypes::GeometryType type
void pushMessage(const QString &message, Qgis::MessageLevel level=Qgis::MessageLevel::Warning) const
Append a message to the context.
QgsMapUnitScale mOffsetMapUnitScale
Offset map unit scale.
double ANALYSIS_EXPORT angle(QgsPoint *p1, QgsPoint *p2, QgsPoint *p3, QgsPoint *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
void copyDataDefinedProperties(QgsSymbolLayer *destLayer) const
Copies all data defined properties of this layer to another symbol layer.
static bool shapeIsFilled(Qgis::MarkerShape shape)
Returns true if a symbol shape has a fill.
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
~QgsFontMarkerSymbolLayer() override
Resolves relative paths into absolute paths and vice versa. Used for writing.
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.
@ RenderMapUnits
Map units.
static QgsMapUnitScale decodeMapUnitScale(const QString &str)
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.
@ ThirdCircle
One third circle (top left third)
double angle() const
Returns the rotation angle for the marker, in degrees clockwise from north.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates the symbol.
QString fontFamily() const
Returns the font family name for the associated font which will be used to render the point.
double mFixedAspectRatio
The marker fixed aspect ratio.
double calculateSize(QgsSymbolRenderContext &context, bool &hasDataDefinedSize) const
Calculates the desired size of the marker, considering data defined size overrides.
bool setPreservedAspectRatio(bool par)
Set preserved the marker aspect ratio between width and height.
QPen mPen
QPen corresponding to marker's stroke style.
static bool updateFontViaStyle(QFont &f, const QString &fontstyle, bool fallback=false)
Updates font with named style and retain all font properties.
void setFillColor(const QColor &color) override
Sets the fill color for the symbol layer.
QColor valueAsColor(int key, const QgsExpressionContext &context, const QColor &defaultColor=QColor(), bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a color.
double strokeWidth() const
Returns the marker's stroke width.
@ Cross
Cross (lines only)
void writePolyline(const QgsPointSequence &line, const QString &layer, const QString &lineStyleName, const QColor &color, double width=-1)
Draw dxf primitives (LWPOLYLINE)
@ PropertyJoinStyle
Line join style.
void drawMarker(QPainter *p, QgsSymbolRenderContext &context)
Draws the marker shape in the specified painter.
QRectF bounds(QPointF point, QgsSymbolRenderContext &context) override
Returns the approximate bounding box of the marker symbol layer, taking into account any data defined...
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
@ PropertyWidth
Symbol width.
~QgsFilledMarkerSymbolLayer() override
#define DEFAULT_RASTERMARKER_ANGLE
QgsMapUnitScale mStrokeWidthMapUnitScale
Stroke width map unit scale.
#define DEFAULT_SIMPLEMARKER_SIZE
double mStrokeWidth
Stroke width.