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 const QString uom = element.attribute( QStringLiteral(
"uom" ) );
1420 p->drawPath(
mPath );
1433 if ( hasDataDefinedSize )
1454 size *= mmMapUnitScaleFactor;
1461 const double halfSize =
size / 2.0;
1478 QColor pc =
mPen.color();
1479 QColor bc =
mBrush.color();
1499 QPointF off( offsetX, offsetY );
1528 t.translate( shift.x() + off.x(), shift.y() - off.y() );
1536 t.scale( halfSize, -halfSize );
1538 polygon = t.map( polygon );
1541 p.reserve( polygon.size() );
1542 for (
int i = 0; i < polygon.size(); i++ )
1547 if (
mBrush.style() != Qt::NoBrush )
1549 if (
mPen.style() != Qt::NoPen )
1554 shift += QPointF( off.x(), -off.y() );
1555 if (
mBrush.style() != Qt::NoBrush )
1557 if (
mPen.style() != Qt::NoPen )
1562 const QPointF pt1 = t.map( QPointF( 0, -halfSize ) );
1563 const QPointF pt2 = t.map( QPointF( 0, halfSize ) );
1565 if (
mPen.style() != Qt::NoPen )
1570 if (
mPen.style() != Qt::NoPen )
1572 const QPointF pt1 = t.map( QPointF( -halfSize, 0 ) );
1573 const QPointF pt2 = t.map( QPointF( halfSize, 0 ) );
1574 const QPointF pt3 = t.map( QPointF( 0, -halfSize ) );
1575 const QPointF pt4 = t.map( QPointF( 0, halfSize ) );
1583 if (
mPen.style() != Qt::NoPen )
1585 const QPointF pt1 = t.map( QPointF( -halfSize, -halfSize ) );
1586 const QPointF pt2 = t.map( QPointF( halfSize, halfSize ) );
1587 const QPointF pt3 = t.map( QPointF( halfSize, -halfSize ) );
1588 const QPointF pt4 = t.map( QPointF( -halfSize, halfSize ) );
1596 if (
mPen.style() != Qt::NoPen )
1598 const QPointF pt1 = t.map( QPointF( -halfSize, halfSize ) );
1599 const QPointF pt2 = t.map( QPointF( 0, 0 ) );
1600 const QPointF pt3 = t.map( QPointF( -halfSize, -halfSize ) );
1686 symbolBounds.adjust( -penWidth / 2.0, -penWidth / 2.0,
1687 penWidth / 2.0, penWidth / 2.0 );
1689 return symbolBounds;
1738 if ( props.contains( QStringLiteral(
"name" ) ) )
1739 name = props[QStringLiteral(
"name" )].toString();
1740 if ( props.contains( QStringLiteral(
"size" ) ) )
1741 size = props[QStringLiteral(
"size" )].toDouble();
1742 if ( props.contains( QStringLiteral(
"angle" ) ) )
1743 angle = props[QStringLiteral(
"angle" )].toDouble();
1744 if ( props.contains( QStringLiteral(
"scale_method" ) ) )
1748 if ( props.contains( QStringLiteral(
"offset" ) ) )
1750 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
1752 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
1754 if ( props.contains( QStringLiteral(
"size_unit" ) ) )
1756 if ( props.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
1758 if ( props.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
1762 if ( props.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
1776 return QStringLiteral(
"FilledMarker" );
1801 map[QStringLiteral(
"size" )] = QString::number(
mSize );
1804 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
1860 attr.unite( mFill->usedAttributes( context ) );
1868 if ( mFill && mFill->hasDataDefinedProperties() )
1877 mFill->setColor(
c );
1882 return mFill ? mFill->color() :
mColor;
1889 || ( mFill && mFill->usesMapUnits() );
1903 const double prevOpacity = mFill->opacity();
1904 mFill->setOpacity( mFill->opacity() * context.
opacity() );
1908 p->setBrush( Qt::red );
1912 p->setBrush( Qt::NoBrush );
1914 p->setPen( Qt::black );
1919 if ( !polygon.isEmpty() )
1925 const QPolygonF poly = path.toFillPolygon();
1931 mFill->setOpacity( prevOpacity );
1946 mColor = QColor( 35, 35, 35 );
1960 if ( props.contains( QStringLiteral(
"name" ) ) )
1961 name = props[QStringLiteral(
"name" )].toString();
1962 if ( props.contains( QStringLiteral(
"size" ) ) )
1963 size = props[QStringLiteral(
"size" )].toDouble();
1964 if ( props.contains( QStringLiteral(
"angle" ) ) )
1965 angle = props[QStringLiteral(
"angle" )].toDouble();
1966 if ( props.contains( QStringLiteral(
"scale_method" ) ) )
1971 if ( props.contains( QStringLiteral(
"size_unit" ) ) )
1973 if ( props.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
1975 if ( props.contains( QStringLiteral(
"fixedAspectRatio" ) ) )
1977 if ( props.contains( QStringLiteral(
"offset" ) ) )
1979 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
1981 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
1983 if ( props.contains( QStringLiteral(
"fill" ) ) )
1988 else if ( props.contains( QStringLiteral(
"color" ) ) )
1992 if ( props.contains( QStringLiteral(
"outline" ) ) )
1997 else if ( props.contains( QStringLiteral(
"outline_color" ) ) )
2001 else if ( props.contains( QStringLiteral(
"line_color" ) ) )
2006 if ( props.contains( QStringLiteral(
"outline-width" ) ) )
2009 m->
setStrokeWidth( props[QStringLiteral(
"outline-width" )].toDouble() );
2011 else if ( props.contains( QStringLiteral(
"outline_width" ) ) )
2013 m->
setStrokeWidth( props[QStringLiteral(
"outline_width" )].toDouble() );
2015 else if ( props.contains( QStringLiteral(
"line_width" ) ) )
2017 m->
setStrokeWidth( props[QStringLiteral(
"line_width" )].toDouble() );
2020 if ( props.contains( QStringLiteral(
"outline_width_unit" ) ) )
2024 else if ( props.contains( QStringLiteral(
"line_width_unit" ) ) )
2028 if ( props.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
2031 if ( props.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
2035 if ( props.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
2044 if ( props.contains( QStringLiteral(
"parameters" ) ) )
2046 const QVariantMap
parameters = props[QStringLiteral(
"parameters" )].toMap();
2055 const QVariantMap::iterator it =
properties.find( QStringLiteral(
"name" ) );
2074 QColor defaultFillColor, defaultStrokeColor;
2076 bool hasFillOpacityParam =
false, hasStrokeParam =
false, hasStrokeWidthParam =
false, hasStrokeOpacityParam =
false;
2077 bool hasDefaultFillColor =
false, hasDefaultFillOpacity =
false, hasDefaultStrokeColor =
false, hasDefaultStrokeWidth =
false, hasDefaultStrokeOpacity =
false;
2079 hasFillOpacityParam, hasDefaultFillOpacity, fillOpacity,
2080 hasStrokeParam, hasDefaultStrokeColor, defaultStrokeColor,
2081 hasStrokeWidthParam, hasDefaultStrokeWidth,
strokeWidth,
2082 hasStrokeOpacityParam, hasDefaultStrokeOpacity, strokeOpacity );
2084 const double newFillOpacity = hasFillOpacityParam ?
fillColor().alphaF() : 1.0;
2085 const double newStrokeOpacity = hasStrokeOpacityParam ?
strokeColor().alphaF() : 1.0;
2087 if ( hasDefaultFillColor )
2089 defaultFillColor.setAlphaF( newFillOpacity );
2092 if ( hasDefaultFillOpacity )
2095 c.setAlphaF( fillOpacity );
2098 if ( hasDefaultStrokeColor )
2100 defaultStrokeColor.setAlphaF( newStrokeOpacity );
2103 if ( hasDefaultStrokeWidth )
2107 if ( hasDefaultStrokeOpacity )
2110 c.setAlphaF( strokeOpacity );
2124 const double widthScaleFactor = 3.465;
2127 mDefaultAspectRatio = svgViewbox.isValid() ? svgViewbox.height() / svgViewbox.width() : 0.0;
2135 if ( aPreservedAspectRatio && !par )
2139 else if ( !aPreservedAspectRatio && par )
2154 return QStringLiteral(
"SvgMarker" );
2174 bool hasDataDefinedSize =
false;
2175 const double scaledWidth = calculateSize( context, hasDataDefinedSize );
2179 if (
static_cast< int >( width ) < 1 || 10000.0 < width )
2186 bool hasDataDefinedAspectRatio =
false;
2187 const double aspectRatio =
calculateAspectRatio( context, scaledWidth, hasDataDefinedAspectRatio );
2230 scaledHeight = svgViewbox.isValid() ? scaledWidth * svgViewbox.height() / svgViewbox.width() : scaledWidth;
2234 QPointF outputOffset;
2236 calculateOffsetAndRotation( context, scaledWidth, scaledHeight, outputOffset,
angle );
2238 p->translate( point + outputOffset );
2244 bool fitsInCache =
true;
2245 bool usePict =
true;
2252 if ( fitsInCache && img.width() > 1 )
2262 QImage transparentImage = img.copy();
2264 p->drawImage( -transparentImage.width() / 2.0, -transparentImage.height() / 2.0, transparentImage );
2268 p->drawImage( -img.width() / 2.0, -img.height() / 2.0, img );
2273 if ( usePict || !fitsInCache )
2275 p->setOpacity( context.
opacity() );
2279 if ( pct.width() > 1 )
2282 _fixQPictureDPI( p );
2283 p->drawPicture( 0, 0, pct );
2291 double QgsSvgMarkerSymbolLayer::calculateSize(
QgsSymbolRenderContext &context,
bool &hasDataDefinedSize )
const
2293 double scaledSize =
mSize;
2297 if ( hasDataDefinedSize )
2305 if ( hasDataDefinedSize )
2312 if ( hasDataDefinedSize && ok )
2317 scaledSize = std::sqrt( scaledSize );
2330 if ( !hasDataDefinedAspectRatio )
2340 const double defaultHeight =
mSize * scaledAspectRatio;
2341 scaledAspectRatio = defaultHeight / scaledSize;
2344 double scaledHeight = scaledSize * scaledAspectRatio;
2351 if ( hasDataDefinedAspectRatio && ok )
2356 scaledHeight = sqrt( scaledHeight );
2363 scaledAspectRatio = scaledHeight / scaledSize;
2365 return scaledAspectRatio;
2368 void QgsSvgMarkerSymbolLayer::calculateOffsetAndRotation(
QgsSymbolRenderContext &context,
double scaledWidth,
double scaledHeight, QPointF &offset,
double &
angle )
const
2373 markerOffset( context, scaledWidth, scaledHeight, offsetX, offsetY );
2374 offset = QPointF( offsetX, offsetY );
2384 if ( hasDataDefinedRotation )
2410 map[QStringLiteral(
"name" )] =
mPath;
2411 map[QStringLiteral(
"size" )] = QString::number(
mSize );
2414 map[QStringLiteral(
"fixedAspectRatio" )] = QString::number(
mFixedAspectRatio );
2415 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
2422 map[QStringLiteral(
"outline_width" )] = QString::number(
mStrokeWidth );
2497 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
2498 element.appendChild( graphicElem );
2508 const double angle = props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toDouble( &ok );
2511 angleFunc = QStringLiteral(
"%1 + %2" ).arg( props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toString() ).arg(
mAngle );
2529 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
2530 if ( graphicElem.isNull() )
2533 QString
path, mimeType;
2540 const QString uom = element.attribute( QStringLiteral(
"uom" ) );
2543 if ( mimeType != QLatin1String(
"image/svg+xml" ) )
2551 const double d = angleFunc.toDouble( &ok );
2577 if ( hasDataDefinedSize )
2583 if ( hasDataDefinedSize && ok )
2597 size *= mmMapUnitScaleFactor;
2611 const double offsetX =
offset.x();
2612 const double offsetY =
offset.y();
2614 QPointF outputOffset( offsetX, offsetY );
2664 QSvgRenderer r( svgContent );
2671 QSizeF outSize( r.defaultSize() );
2672 outSize.scale(
size,
size, Qt::KeepAspectRatio );
2678 p.translate( r.defaultSize().width() / 2.0, r.defaultSize().height() / 2.0 );
2680 p.translate( -r.defaultSize().width() / 2.0, -r.defaultSize().height() / 2.0 );
2682 pd.
setShift( shift + QPointF( outputOffset.x(), -outputOffset.y() ) );
2683 pd.
setOutputSize( QRectF( -outSize.width() / 2.0, -outSize.height() / 2.0, outSize.width(), outSize.height() ) );
2692 bool hasDataDefinedSize =
false;
2693 double scaledWidth = calculateSize( context, hasDataDefinedSize );
2695 bool hasDataDefinedAspectRatio =
false;
2696 const double aspectRatio =
calculateAspectRatio( context, scaledWidth, hasDataDefinedAspectRatio );
2703 if (
static_cast< int >( scaledWidth ) < 1 || 10000.0 < scaledWidth )
2708 QPointF outputOffset;
2710 calculateOffsetAndRotation( context, scaledWidth, scaledHeight, outputOffset,
angle );
2749 scaledHeight = svgViewbox.isValid() ? scaledWidth * svgViewbox.height() / svgViewbox.width() : scaledWidth;
2753 QTransform transform;
2755 transform.translate( point.x() + outputOffset.x(), point.y() + outputOffset.y() );
2758 transform.rotate(
angle );
2763 QRectF symbolBounds = transform.mapRect( QRectF( -scaledWidth / 2.0,
2764 -scaledHeight / 2.0,
2772 return symbolBounds;
2796 if ( props.contains( QStringLiteral(
"imageFile" ) ) )
2797 path = props[QStringLiteral(
"imageFile" )].toString();
2798 if ( props.contains( QStringLiteral(
"size" ) ) )
2799 size = props[QStringLiteral(
"size" )].toDouble();
2800 if ( props.contains( QStringLiteral(
"angle" ) ) )
2801 angle = props[QStringLiteral(
"angle" )].toDouble();
2802 if ( props.contains( QStringLiteral(
"scale_method" ) ) )
2807 if ( props.contains( QStringLiteral(
"alpha" ) ) )
2809 m->
setOpacity( props[QStringLiteral(
"alpha" )].toDouble() );
2812 if ( props.contains( QStringLiteral(
"size_unit" ) ) )
2814 if ( props.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
2816 if ( props.contains( QStringLiteral(
"fixedAspectRatio" ) ) )
2819 if ( props.contains( QStringLiteral(
"offset" ) ) )
2821 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
2823 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
2826 if ( props.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
2830 if ( props.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
2843 const QVariantMap::iterator it =
properties.find( QStringLiteral(
"name" ) );
2844 if ( it !=
properties.end() && it.value().type() == QVariant::String )
2862 if ( aPreservedAspectRatio && !par )
2866 else if ( !aPreservedAspectRatio && par )
2885 return QStringLiteral(
"RasterMarker" );
2901 if (
path.isEmpty() )
2905 double height = 0.0;
2907 bool hasDataDefinedSize =
false;
2908 const double scaledSize = calculateSize( context, hasDataDefinedSize );
2910 bool hasDataDefinedAspectRatio =
false;
2911 const double aspectRatio =
calculateAspectRatio( context, scaledSize, hasDataDefinedAspectRatio );
2913 QPointF outputOffset;
2920 if (
size.isEmpty() )
2923 width = ( scaledSize *
static_cast< double >(
size.width() ) ) / 100.0;
2924 height = ( scaledSize *
static_cast< double >(
size.height() ) ) / 100.0;
2927 if (
static_cast< int >( width ) < 1 || 10000.0 < width ||
static_cast< int >( height ) < 1 || 10000.0 < height )
2930 calculateOffsetAndRotation( context, width, height, outputOffset,
angle );
2940 if ( !
size.isNull() &&
size.isValid() &&
size.width() > 0 )
2942 height = width * (
static_cast< double >(
size.height() ) /
static_cast< double >(
size.width() ) );
2947 if (
static_cast< int >( width ) < 1 || 10000.0 < width )
2950 calculateOffsetAndRotation( context, scaledSize, scaledSize * ( height / width ), outputOffset,
angle );
2954 p->translate( point + outputOffset );
2970 if ( !img.isNull() )
2977 p->drawImage( -img.width() / 2.0, -img.height() / 2.0, img );
2981 double QgsRasterMarkerSymbolLayer::calculateSize(
QgsSymbolRenderContext &context,
bool &hasDataDefinedSize )
const
2983 double scaledSize =
mSize;
2987 if ( hasDataDefinedSize )
2995 if ( hasDataDefinedSize )
3002 if ( hasDataDefinedSize && ok )
3007 scaledSize = std::sqrt( scaledSize );
3020 if ( !hasDataDefinedAspectRatio )
3030 const double defaultHeight =
mSize * scaledAspectRatio;
3031 scaledAspectRatio = defaultHeight / scaledSize;
3034 double scaledHeight = scaledSize * scaledAspectRatio;
3041 if ( hasDataDefinedAspectRatio && ok )
3046 scaledHeight = sqrt( scaledHeight );
3053 scaledAspectRatio = scaledHeight / scaledSize;
3055 return scaledAspectRatio;
3058 void QgsRasterMarkerSymbolLayer::calculateOffsetAndRotation(
QgsSymbolRenderContext &context,
double scaledWidth,
double scaledHeight, QPointF &offset,
double &
angle )
const
3063 markerOffset( context, scaledWidth, scaledHeight, offsetX, offsetY );
3064 offset = QPointF( offsetX, offsetY );
3074 if ( hasDataDefinedRotation )
3095 map[QStringLiteral(
"imageFile" )] =
mPath;
3096 map[QStringLiteral(
"size" )] = QString::number(
mSize );
3099 map[QStringLiteral(
"fixedAspectRatio" )] = QString::number(
mFixedAspectRatio );
3100 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
3101 map[QStringLiteral(
"alpha" )] = QString::number(
mOpacity );
3151 bool hasDataDefinedSize =
false;
3152 const double scaledSize = calculateSize( context, hasDataDefinedSize );
3154 bool hasDataDefinedAspectRatio =
false;
3155 const double aspectRatio =
calculateAspectRatio( context, scaledSize, hasDataDefinedAspectRatio );
3159 if (
static_cast< int >( scaledSize ) < 1 || 10000.0 < scaledSize )
3164 QPointF outputOffset;
3166 calculateOffsetAndRotation( context, scaledSize, scaledSize * ( height / width ), outputOffset,
angle );
3168 QTransform transform;
3171 transform.translate( point.x() + outputOffset.x(), point.y() + outputOffset.y() );
3174 transform.rotate(
angle );
3176 QRectF symbolBounds = transform.mapRect( QRectF( -width / 2.0,
3181 return symbolBounds;
3193 mOrigSize = pointSize;
3213 if ( props.contains( QStringLiteral(
"font" ) ) )
3214 fontFamily = props[QStringLiteral(
"font" )].toString();
3215 if ( props.contains( QStringLiteral(
"chr" ) ) && props[QStringLiteral(
"chr" )].toString().length() > 0 )
3216 string = props[QStringLiteral(
"chr" )].toString();
3217 if ( props.contains( QStringLiteral(
"size" ) ) )
3218 pointSize = props[QStringLiteral(
"size" )].toDouble();
3219 if ( props.contains( QStringLiteral(
"color" ) ) )
3221 if ( props.contains( QStringLiteral(
"angle" ) ) )
3222 angle = props[QStringLiteral(
"angle" )].toDouble();
3226 if ( props.contains( QStringLiteral(
"font_style" ) ) )
3227 m->
setFontStyle( props[QStringLiteral(
"font_style" )].toString() );
3228 if ( props.contains( QStringLiteral(
"outline_color" ) ) )
3230 if ( props.contains( QStringLiteral(
"outline_width" ) ) )
3231 m->
setStrokeWidth( props[QStringLiteral(
"outline_width" )].toDouble() );
3232 if ( props.contains( QStringLiteral(
"offset" ) ) )
3234 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
3236 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
3238 if ( props.contains( QStringLiteral(
"size_unit" ) ) )
3240 if ( props.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
3242 if ( props.contains( QStringLiteral(
"outline_width_unit" ) ) )
3244 if ( props.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
3246 if ( props.contains( QStringLiteral(
"joinstyle" ) ) )
3248 if ( props.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
3250 if ( props.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
3260 return QStringLiteral(
"FontMarker" );
3265 QColor brushColor =
mColor;
3266 QColor penColor = mStrokeColor;
3268 brushColor.setAlphaF(
mColor.alphaF() * context.
opacity() );
3269 penColor.setAlphaF( mStrokeColor.alphaF() * context.
opacity() );
3271 mBrush = QBrush( brushColor );
3272 mPen = QPen( penColor );
3273 mPen.setJoinStyle( mPenJoinStyle );
3276 mFont = QFont( mFontFamily );
3277 if ( !mFontStyle.isEmpty() )
3285 if ( mNonZeroFontSize && sizePixels > MAX_FONT_CHARACTER_SIZE_IN_PIXELS )
3290 mFontSizeScale = sizePixels / MAX_FONT_CHARACTER_SIZE_IN_PIXELS;
3291 sizePixels = MAX_FONT_CHARACTER_SIZE_IN_PIXELS;
3294 mFontSizeScale = 1.0;
3298 mFont.setPixelSize( std::max( 2,
static_cast< int >( std::round( sizePixels ) ) ) );
3299 mFontMetrics.reset(
new QFontMetrics( mFont ) );
3300 mChrWidth = mFontMetrics->horizontalAdvance( mString );
3301 mChrOffset = QPointF( mChrWidth / 2.0, -mFontMetrics->ascent() / 2.0 );
3308 if ( mUseCachedPath )
3310 QPointF chrOffset = mChrOffset;
3312 const QString charToRender = characterToRender( context, chrOffset, chrWidth );
3313 mCachedPath = QPainterPath();
3314 mCachedPath.addText( -chrOffset.x(), -chrOffset.y(), mFont, charToRender );
3323 QString QgsFontMarkerSymbolLayer::characterToRender(
QgsSymbolRenderContext &context, QPointF &charOffset,
double &charWidth )
3325 charOffset = mChrOffset;
3326 QString stringToRender = mString;
3331 if ( stringToRender != mString )
3333 charWidth = mFontMetrics->horizontalAdvance( stringToRender );
3334 charOffset = QPointF( charWidth / 2.0, -mFontMetrics->ascent() / 2.0 );
3337 return stringToRender;
3342 bool &hasDataDefinedRotation,
3344 double &
angle )
const
3349 markerOffset( context, scaledSize, scaledSize, offsetX, offsetY );
3350 offset = QPointF( offsetX, offsetY );
3366 if ( hasDataDefinedRotation )
3390 double scaledSize =
mSize;
3394 if ( hasDataDefinedSize )
3400 if ( hasDataDefinedSize && ok )
3405 scaledSize = std::sqrt( scaledSize );
3417 if ( !p || !mNonZeroFontSize )
3420 QTransform transform;
3423 QColor brushColor =
mColor;
3432 brushColor.setAlphaF( brushColor.alphaF() * context.
opacity() );
3434 mBrush.setColor( brushColor );
3436 QColor penColor = mStrokeColor;
3442 penColor.setAlphaF( penColor.alphaF() * context.
opacity() );
3466 p->setBrush( mBrush );
3469 mPen.setColor( penColor );
3470 mPen.setWidthF( penWidth );
3475 p->setPen( Qt::NoPen );
3482 mFont.setFamily( ok ?
fontFamily : mFontFamily );
3492 mFontMetrics.reset(
new QFontMetrics( mFont ) );
3495 QPointF chrOffset = mChrOffset;
3497 const QString charToRender = characterToRender( context, chrOffset, chrWidth );
3499 const double sizeToRender = calculateSize( context );
3501 bool hasDataDefinedRotation =
false;
3504 calculateOffsetAndRotation( context, sizeToRender, hasDataDefinedRotation,
offset,
angle );
3506 p->translate( point.x() +
offset.x(), point.y() +
offset.y() );
3509 transform.rotate(
angle );
3513 const double s = sizeToRender / mOrigSize;
3514 transform.scale( s, s );
3518 transform.scale( mFontSizeScale, mFontSizeScale );
3520 if ( mUseCachedPath )
3522 p->drawPath( transform.map( mCachedPath ) );
3527 path.addText( -chrOffset.x(), -chrOffset.y(), mFont, charToRender );
3528 p->drawPath( transform.map( path ) );
3535 props[QStringLiteral(
"font" )] = mFontFamily;
3536 props[QStringLiteral(
"font_style" )] = mFontStyle;
3537 props[QStringLiteral(
"chr" )] = mString;
3538 props[QStringLiteral(
"size" )] = QString::number(
mSize );
3543 props[QStringLiteral(
"outline_width" )] = QString::number( mStrokeWidth );
3547 props[QStringLiteral(
"angle" )] = QString::number(
mAngle );
3580 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
3581 element.appendChild( graphicElem );
3583 const QString fontPath = QStringLiteral(
"ttf://%1" ).arg( mFontFamily );
3584 int markIndex = !mString.isEmpty() ? mString.at( 0 ).unicode() : 0;
3591 const double angle = props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toDouble( &ok );
3594 angleFunc = QStringLiteral(
"%1 + %2" ).arg( props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toString() ).arg(
mAngle );
3616 QPointF chrOffset = mChrOffset;
3617 double chrWidth = mChrWidth;
3619 ( void )characterToRender( context, chrOffset, chrWidth );
3621 if ( !mFontMetrics )
3622 mFontMetrics.reset(
new QFontMetrics( mFont ) );
3624 double scaledSize = calculateSize( context );
3627 chrWidth *= scaledSize / mOrigSize;
3629 chrWidth *= mFontSizeScale;
3631 bool hasDataDefinedRotation =
false;
3634 calculateOffsetAndRotation( context, scaledSize, hasDataDefinedRotation,
offset,
angle );
3637 QTransform transform;
3640 transform.translate( point.x() +
offset.x(), point.y() +
offset.y() );
3643 transform.rotate(
angle );
3645 QRectF symbolBounds = transform.mapRect( QRectF( -chrWidth / 2.0,
3649 return symbolBounds;
3656 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
3657 if ( graphicElem.isNull() )
3660 QString name, format;
3668 if ( !name.startsWith( QLatin1String(
"ttf://" ) ) || format != QLatin1String(
"ttf" ) )
3678 const double d = angleFunc.toDouble( &ok );
3686 const QString uom = element.attribute( QStringLiteral(
"uom" ) );
3709 QMap<QString, QgsProperty>::iterator it =
mParameters.begin();
3721 QMap<QString, QgsProperty>::const_iterator it =
mParameters.constBegin();
3724 attrs.unite( it.value().referencedFields( context.
expressionContext(),
true ) );
@ DynamicRotation
Rotation of symbol may be changed during rendering and symbol should not be cached.
ScaleMethod
Scale methods.
@ ScaleDiameter
Calculate scale by the diameter.
@ ScaleArea
Calculate scale by the area.
MarkerShape
Marker shapes.
@ EquilateralTriangle
Equilateral triangle.
@ SemiCircle
Semi circle (top half)
@ QuarterCircle
Quarter circle (top left quarter)
@ LeftHalfTriangle
Left half of triangle.
@ ArrowHead
Right facing arrow head (unfilled, lines only)
@ AsteriskFill
A filled asterisk shape (since QGIS 3.18)
@ Octagon
Octagon (since QGIS 3.18)
@ HalfArc
A line-only half arc (since QGIS 3.20)
@ QuarterSquare
Quarter square (top left quarter)
@ Cross2
Rotated cross (lines only), 'x' shape.
@ ArrowHeadFilled
Right facing filled arrow head.
@ HalfSquare
Half square (left half)
@ CrossFill
Solid filled cross.
@ RightHalfTriangle
Right half of triangle.
@ ThirdCircle
One third circle (top left third)
@ ThirdArc
A line-only one third arc (since QGIS 3.20)
@ SquareWithCorners
A square with diagonal corners (since QGIS 3.18)
@ QuarterArc
A line-only one quarter arc (since QGIS 3.20)
@ Cross
Cross (lines only)
@ DiagonalHalfSquare
Diagonal half square (bottom left half)
@ RenderingSubSymbol
Set whenever a sub-symbol of a parent symbol is currently being rendered. Can be used during symbol a...
@ RenderSymbolPreview
The render is for a symbol preview only and map based properties may not be available,...
@ RenderBlocking
Render and load remote sources in the same thread to ensure rendering remote sources (svg and images)...
QColor valueAsColor(int key, const QgsExpressionContext &context, const QColor &defaultColor=QColor(), bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a color.
double valueAsDouble(int key, const QgsExpressionContext &context, double defaultValue=0.0, bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a double.
QString valueAsString(int key, const QgsExpressionContext &context, const QString &defaultString=QString(), bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a string.
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...
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)
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)
static double mapUnitScaleFactor(double scale, QgsUnitTypes::RenderUnit symbolUnits, QgsUnitTypes::DistanceUnit mapUnits, double mapUnitsPerPixel=1.0)
Returns scale factor for conversion to map units.
QgsUnitTypes::DistanceUnit mapUnits() const
Retrieve map units.
void writePolygon(const QgsRingSequence &polygon, const QString &layer, const QString &hatchPattern, const QColor &color)
Draw dxf filled polygon (HATCH)
double symbologyScale() const
Returns the reference scale for output.
void clipValueToMapUnitScale(double &value, const QgsMapUnitScale &scale, double pixelToMMFactor) const
Clips value to scale minimum/maximum.
void writePolyline(const QgsPointSequence &line, const QString &layer, const QString &lineStyleName, const QColor &color, double width=-1)
Draw dxf primitives (LWPOLYLINE)
A paint device for drawing into dxf files.
void setShift(QPointF shift)
void setLayer(const QString &layer)
void setOutputSize(const QRectF &r)
void setDrawingSize(QSizeF size)
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
bool hasGeometry() const
Returns true if the feature has an associated geometry.
A fill symbol type, for rendering Polygon and MultiPolygon geometries.
static QgsFillSymbol * createSimple(const QVariantMap &properties)
Create a fill symbol with one symbol layer: SimpleFill with specified properties.
Filled marker symbol layer, consisting of a shape which is rendered using a QgsFillSymbol.
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
QColor color() const override
Returns the "representative" color of the symbol layer.
QgsFilledMarkerSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
bool hasDataDefinedProperties() const override
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
QgsSymbol * subSymbol() override
Returns the symbol's sub symbol, if present.
~QgsFilledMarkerSymbolLayer() override
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer's subsymbol. takes ownership of the passed symbol.
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
void setColor(const QColor &c) override
Sets the "representative" color for the symbol layer.
QString layerType() const override
Returns a string that represents this layer type.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsFilledMarkerSymbolLayer.
QgsFilledMarkerSymbolLayer(Qgis::MarkerShape shape=Qgis::MarkerShape::Circle, double size=DEFAULT_SIMPLEMARKER_SIZE, double angle=DEFAULT_SIMPLEMARKER_ANGLE, Qgis::ScaleMethod scaleMethod=DEFAULT_SCALE_METHOD)
Constructor for QgsFilledMarkerSymbolLayer.
~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.
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...
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 stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
QString layerType() const override
Returns a string that represents this layer type.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsFontMarkerSymbolLayer from a property map (see properties())
static QString translateNamedStyle(const QString &namedStyle)
Returns the localized named style of a font, if such a translation is available.
static bool fontFamilyMatchOnSystem(const QString &family, QString *chosen=nullptr, bool *match=nullptr)
Check whether font family is on system.
static bool updateFontViaStyle(QFont &f, const QString &fontstyle, bool fallback=false)
Updates font with named style and retain all font properties.
QgsWkbTypes::GeometryType type
QSize originalSize(const QString &path, bool blocking=false) const
Returns the original size (in pixels) 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, bool *isMissing=nullptr)
Returns the specified path rendered as an image.
static void adjustHueSaturation(QImage &image, double saturation, const QColor &colorizeColor=QColor(), double colorizeStrength=1.0, QgsFeedback *feedback=nullptr)
Alter the hue or saturation of a QImage.
Perform transforms between map coordinates and device coordinates.
double mapUnitsPerPixel() const
Returns the current map units per pixel.
double mapRotation() const
Returns the current map rotation in degrees (clockwise).
Struct for storing maximum and minimum scales for measurements in map units.
Abstract base class for marker symbol layers.
QPointF offset() const
Returns the marker's offset, which is the horizontal and vertical displacement which the rendered mar...
double mLineAngle
Line rotation angle (see setLineAngle() for details)
HorizontalAnchorPoint
Symbol horizontal anchor points.
void 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.
QgsUnitTypes::RenderUnit mOffsetUnit
Offset units.
void setSizeUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the symbol's size.
void setVerticalAnchorPoint(VerticalAnchorPoint v)
Sets the vertical anchor point for positioning the symbol.
void setOutputUnit(QgsUnitTypes::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QPointF mOffset
Marker offset.
void setHorizontalAnchorPoint(HorizontalAnchorPoint h)
Sets the horizontal anchor point for positioning the symbol.
QgsMapUnitScale mapUnitScale() const override
void setOffset(QPointF offset)
Sets the marker's offset, which is the horizontal and vertical displacement which the rendered marker...
void setSizeMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the symbol's size.
double size() const
Returns the symbol size.
QgsMapUnitScale mOffsetMapUnitScale
Offset map unit scale.
HorizontalAnchorPoint mHorizontalAnchorPoint
Horizontal anchor point.
static QPointF _rotatedOffset(QPointF offset, double angle)
Adjusts a marker offset to account for rotation.
Qgis::ScaleMethod mScaleMethod
Marker size scaling method.
QgsMapUnitScale mSizeMapUnitScale
Marker size map unit scale.
VerticalAnchorPoint
Symbol vertical anchor points.
void markerOffset(QgsSymbolRenderContext &context, double &offsetX, double &offsetY) const
Calculates the required marker offset, including both the symbol offset and any displacement required...
VerticalAnchorPoint mVerticalAnchorPoint
Vertical anchor point.
QgsUnitTypes::RenderUnit mSizeUnit
Marker size unit.
void setOffsetUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the symbol's offset.
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.
QgsUnitTypes::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
double angle() const
Returns the rotation angle for the marker, in degrees clockwise from north.
void setMapUnitScale(const QgsMapUnitScale &scale) override
Resolves relative paths into absolute paths and vice versa.
Point geometry type, with support for z-dimension and m-values.
QVariant value(int key, const QgsExpressionContext &context, const QVariant &defaultValue=QVariant()) const override
Returns the calculated value of the property with the specified key from within the collection.
bool isActive(int key) const override
Returns true if the collection contains an active property with the specified key.
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.
Raster marker symbol layer class.
double mFixedAspectRatio
The marker fixed aspect ratio.
QColor color() const override
Returns the "representative" color of the symbol layer.
QRectF bounds(QPointF point, QgsSymbolRenderContext &context) override
Returns the approximate bounding box of the marker symbol layer, taking into account any data defined...
void renderPoint(QPointF point, QgsSymbolRenderContext &context) override
Renders a marker at the specified point.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
QgsMapUnitScale mapUnitScale() const override
void 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.
double defaultAspectRatio() const
Returns the default marker aspect ratio between width and height, 0 if not yet calculated.
void setFixedAspectRatio(double ratio)
Set the marker aspect ratio between width and height to be used in rendering, if the value set is low...
void setMapUnitScale(const QgsMapUnitScale &scale) override
QgsRasterMarkerSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
bool preservedAspectRatio() const
Returns the preserved aspect ratio value, true if fixed aspect ratio has been lower or equal to 0.
static void resolvePaths(QVariantMap &properties, const QgsPathResolver &pathResolver, bool saving)
Turns relative paths in properties map to absolute when reading and vice versa when writing.
~QgsRasterMarkerSymbolLayer() override
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a raster marker symbol layer from a string map of properties.
double mOpacity
The marker default opacity.
double updateDefaultAspectRatio()
Calculates the default marker aspect ratio between width and height.
double mDefaultAspectRatio
The marker default aspect ratio.
bool setPreservedAspectRatio(bool par)
Set preserved the marker aspect ratio between width and height.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
QString layerType() const override
Returns a string that represents this layer type.
double opacity() const
Returns the marker opacity.
The class is used as a container of context for various read/write operations on other objects.
void pushMessage(const QString &message, Qgis::MessageLevel level=Qgis::MessageLevel::Warning) const
Append a message to the context.
Contains information about the context of a rendering operation.
double scaleFactor() const
Returns the scaling factor for the render to convert painter units to physical sizes.
QPainter * painter()
Returns the destination QPainter for the render operation.
QgsExpressionContext & expressionContext()
Gets the expression context.
const QgsMapToPixel & mapToPixel() const
Returns the context's map to pixel transform, which transforms between map coordinates and device coo...
void setPainterFlagsUsingContext(QPainter *painter=nullptr) const
Sets relevant flags on a destination painter, using the flags and settings currently defined for the ...
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).
bool forceVectorOutput() const
Returns true if rendering operations should use vector operations instead of any faster raster shortc...
void setFlag(Qgis::RenderContextFlag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected)
QColor selectionColor() const
Returns the color to use when rendering selected features.
QgsFeedback * feedback() const
Returns the feedback object that can be queried regularly during rendering to check if rendering shou...
Qgis::RenderContextFlags flags() const
Returns combination of flags used for rendering.
const QgsPathResolver & pathResolver() const
Returns the path resolver for conversion between relative and absolute paths during rendering operati...
Scoped object for saving and restoring a QPainter object's state.
Abstract base class for simple marker symbol layers.
void renderPoint(QPointF point, QgsSymbolRenderContext &context) override
Renders a marker at the specified point.
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
void calculateOffsetAndRotation(QgsSymbolRenderContext &context, double scaledSize, bool &hasDataDefinedRotation, QPointF &offset, double &angle) const
Calculates the marker offset and rotation.
Qgis::MarkerShape mShape
Symbol shape.
QPainterPath mPath
Painter path representing shape. If mPolygon is empty then the shape is stored in mPath.
bool shapeToPolygon(Qgis::MarkerShape shape, QPolygonF &polygon) const
Creates a polygon representing the specified shape.
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
static QList< Qgis::MarkerShape > availableShapes()
Returns a list of all available shape types.
~QgsSimpleMarkerSymbolLayerBase() override
static bool shapeIsFilled(Qgis::MarkerShape shape)
Returns true if a symbol shape has a fill.
QPolygonF mPolygon
Polygon of points in shape. If polygon is empty then shape is using mPath.
Qgis::MarkerShape shape() const
Returns the shape for the rendered marker symbol.
QRectF bounds(QPointF point, QgsSymbolRenderContext &context) override
Returns the approximate bounding box of the marker symbol layer, taking into account any data defined...
QgsSimpleMarkerSymbolLayerBase(Qgis::MarkerShape shape=Qgis::MarkerShape::Circle, double size=DEFAULT_SIMPLEMARKER_SIZE, double angle=DEFAULT_SIMPLEMARKER_ANGLE, Qgis::ScaleMethod scaleMethod=DEFAULT_SCALE_METHOD)
Constructor for QgsSimpleMarkerSymbolLayerBase.
static QString encodeShape(Qgis::MarkerShape shape)
Encodes a shape to its string representation.
double calculateSize(QgsSymbolRenderContext &context, bool &hasDataDefinedSize) const
Calculates the desired size of the marker, considering data defined size overrides.
static Qgis::MarkerShape decodeShape(const QString &name, bool *ok=nullptr)
Attempts to decode a string representation of a shape name to the corresponding shape.
bool prepareMarkerPath(Qgis::MarkerShape symbol)
Prepares the layer for drawing the specified shape (QPainterPath version)
bool prepareMarkerShape(Qgis::MarkerShape shape)
Prepares the layer for drawing the specified shape (QPolygonF version)
Simple marker symbol layer, consisting of a rendered shape with solid fill color and an stroke.
QPen mSelPen
QPen to use as stroke of selected symbols.
void setStrokeWidthUnit(QgsUnitTypes::RenderUnit u)
Sets the unit for the width of the marker's stroke.
void setColor(const QColor &color) override
Sets the "representative" color for the symbol layer.
QColor mStrokeColor
Stroke color.
QImage mSelCache
Cached image of selected marker, if using cached version.
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).
QgsUnitTypes::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
void drawMarker(QPainter *p, QgsSymbolRenderContext &context)
Draws the marker shape in the specified painter.
QPen mPen
QPen corresponding to marker's stroke style.
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
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.
void setOutputUnit(QgsUnitTypes::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
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)
QgsUnitTypes::RenderUnit mStrokeWidthUnit
Stroke width units.
bool mUsingCache
true if using cached images of markers for drawing.
void setPenCapStyle(Qt::PenCapStyle style)
Sets the marker's stroke cap style (e.g., flat, round, etc).
bool writeDxf(QgsDxfExport &e, double mmMapUnitScaleFactor, const QString &layerName, QgsSymbolRenderContext &context, QPointF shift=QPointF(0.0, 0.0)) const override
write as DXF
void writeSldMarker(QDomDocument &doc, QDomElement &element, const QVariantMap &props) const override
Writes the symbol layer definition as a SLD XML element.
static const int MAXIMUM_CACHE_WIDTH
Maximum width/height of cache image.
QString ogrFeatureStyle(double mmScaleFactor, double mapUnitScaleFactor) const override
bool prepareCache(QgsSymbolRenderContext &context)
Prepares cache image.
QgsMapUnitScale mStrokeWidthMapUnitScale
Stroke width map unit scale.
QgsSimpleMarkerSymbolLayer(Qgis::MarkerShape shape=Qgis::MarkerShape::Circle, double size=DEFAULT_SIMPLEMARKER_SIZE, double angle=DEFAULT_SIMPLEMARKER_ANGLE, Qgis::ScaleMethod scaleMethod=DEFAULT_SCALE_METHOD, const QColor &color=DEFAULT_SIMPLEMARKER_COLOR, const QColor &strokeColor=DEFAULT_SIMPLEMARKER_BORDERCOLOR, Qt::PenJoinStyle penJoinStyle=DEFAULT_SIMPLEMARKER_JOINSTYLE)
Constructor for QgsSimpleMarkerSymbolLayer.
double strokeWidth() const
Returns the width of the marker's stroke.
Qt::PenJoinStyle mPenJoinStyle
Stroke pen join style.
void renderPoint(QPointF point, QgsSymbolRenderContext &context) override
Renders a marker at the specified point.
QSizeF svgViewboxSize(const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth, double widthScaleFactor, double fixedAspectRatio=0, bool blocking=false, const QMap< QString, QString > ¶meters=QMap< QString, QString >())
Calculates the viewbox size of a (possibly cached) SVG file.
QPicture svgAsPicture(const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth, double widthScaleFactor, bool forceVectorOutput=false, double fixedAspectRatio=0, bool blocking=false, const QMap< QString, QString > ¶meters=QMap< QString, QString >())
Returns an SVG drawing as a QPicture.
void containsParams(const QString &path, bool &hasFillParam, QColor &defaultFillColor, bool &hasStrokeParam, QColor &defaultStrokeColor, bool &hasStrokeWidthParam, double &defaultStrokeWidth, bool blocking=false) const
Tests if an SVG file contains parameters for fill, stroke color, stroke width.
QImage svgAsImage(const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth, double widthScaleFactor, bool &fitsInCache, double fixedAspectRatio=0, bool blocking=false, const QMap< QString, QString > ¶meters=QMap< QString, QString >())
Returns an SVG drawing as a QImage.
QByteArray svgContent(const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth, double widthScaleFactor, double fixedAspectRatio=0, bool blocking=false, const QMap< QString, QString > ¶meters=QMap< QString, QString >(), bool *isMissingImage=nullptr)
Gets the SVG content corresponding to the given path.
QgsSvgMarkerSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
QColor fillColor() const override
Returns the fill color for the symbol layer.
QgsMapUnitScale mapUnitScale() const override
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates the symbol.
double mDefaultAspectRatio
The marker default aspect ratio.
QgsUnitTypes::RenderUnit mStrokeWidthUnit
QString layerType() const override
Returns a string that represents this layer type.
void setStrokeWidthMapUnitScale(const QgsMapUnitScale &scale)
void setOutputUnit(QgsUnitTypes::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QString path() const
Returns the marker SVG path.
QgsUnitTypes::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
bool preservedAspectRatio() const
Returns the preserved aspect ratio value, true if fixed aspect ratio has been lower or equal to 0.
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
void setStrokeWidth(double w)
void 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...
void setStrokeWidthUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the stroke width.
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 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
QMap< QString, QgsProperty > parameters() const
Returns the dynamic SVG parameters.
QgsSvgMarkerSymbolLayer(const QString &path, double size=DEFAULT_SVGMARKER_SIZE, double angle=DEFAULT_SVGMARKER_ANGLE, Qgis::ScaleMethod scaleMethod=DEFAULT_SCALE_METHOD)
Constructs SVG marker symbol layer with picture from given absolute path to a SVG file.
void writeSldMarker(QDomDocument &doc, QDomElement &element, const QVariantMap &props) const override
Writes the symbol layer definition as a SLD XML element.
void renderPoint(QPointF point, QgsSymbolRenderContext &context) override
Renders a marker at the specified point.
~QgsSvgMarkerSymbolLayer() override
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
static void resolvePaths(QVariantMap &properties, const QgsPathResolver &pathResolver, bool saving)
Turns relative paths in properties map to absolute when reading and vice versa when writing.
QgsMapUnitScale mStrokeWidthMapUnitScale
void setParameters(const QMap< QString, QgsProperty > ¶meters)
Sets the dynamic SVG parameters.
double mFixedAspectRatio
The marker fixed aspect ratio.
bool writeDxf(QgsDxfExport &e, double mmMapUnitScaleFactor, const QString &layerName, QgsSymbolRenderContext &context, QPointF shift=QPointF(0.0, 0.0)) const override
write as DXF
void setFixedAspectRatio(double ratio)
Set the marker aspect ratio between width and height to be used in rendering, if the value set is low...
void setPath(const QString &path)
Set the marker SVG path.
static bool externalMarkerFromSld(QDomElement &element, QString &path, QString &format, int &markIndex, QColor &color, double &size)
static bool rotationFromSldElement(QDomElement &element, QString &rotationFunc)
static QString encodePenStyle(Qt::PenStyle style)
static Qt::PenJoinStyle decodePenJoinStyle(const QString &str)
static QString encodeMapUnitScale(const QgsMapUnitScale &mapUnitScale)
static QgsStringMap evaluatePropertiesMap(const QMap< QString, QgsProperty > &propertiesMap, const QgsExpressionContext &context)
Evaluates a map of properties using the given context and returns a variant map with evaluated expres...
static bool displacementFromSldElement(QDomElement &element, QPointF &offset)
static QColor decodeColor(const QString &str)
static QString svgSymbolPathToName(const QString &path, const QgsPathResolver &pathResolver)
Determines an SVG symbol's name from its path.
static QPointF toPoint(const QVariant &value, bool *ok=nullptr)
Converts a value to a point.
static 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,...
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 Qt::PenCapStyle decodePenCapStyle(const QString &str)
static bool externalGraphicFromSld(QDomElement &element, QString &path, QString &mime, QColor &color, double &size)
static void parametricSvgToSld(QDomDocument &doc, QDomElement &graphicElem, const QString &path, const QColor &fillColor, double size, const QColor &strokeColor, double strokeWidth)
Encodes a reference to a parametric SVG into SLD, as a succession of parametric SVG using URL paramet...
static Qgis::ScaleMethod decodeScaleMethod(const QString &str)
Decodes a symbol scale method from a string.
static QString encodePenCapStyle(Qt::PenCapStyle style)
static void externalMarkerToSld(QDomDocument &doc, QDomElement &element, const QString &path, const QString &format, int *markIndex=nullptr, const QColor &color=QColor(), double size=-1)
static double sizeInPixelsFromSldUom(const QString &uom, double size)
Returns the size scaled in pixels according to the uom attribute.
static bool wellKnownMarkerFromSld(QDomElement &element, QString &name, QColor &color, QColor &strokeColor, Qt::PenStyle &strokeStyle, double &strokeWidth, double &size)
static void createDisplacementElement(QDomDocument &doc, QDomElement &element, QPointF offset)
static QString svgSymbolNameToPath(const QString &name, const QgsPathResolver &pathResolver)
Determines an SVG symbol's path from its name.
static QString encodeColor(const QColor &color)
static double estimateMaxSymbolBleed(QgsSymbol *symbol, const QgsRenderContext &context)
Returns the maximum estimated bleed for the symbol.
static void wellKnownMarkerToSld(QDomDocument &doc, QDomElement &element, const QString &name, const QColor &color, const QColor &strokeColor, Qt::PenStyle strokeStyle, double strokeWidth=-1, double size=-1)
static QString encodeScaleMethod(Qgis::ScaleMethod scaleMethod)
Encodes a symbol scale method to a string.
static Qt::PenStyle decodePenStyle(const QString &str)
static void createRotationElement(QDomDocument &doc, QDomElement &element, const QString &rotationFunc)
static QString encodePoint(QPointF point)
Encodes a QPointF to a string.
static QString encodePenJoinStyle(Qt::PenJoinStyle style)
static QPointF decodePoint(const QString &string)
Decodes a QSizeF from a string.
@ PropertyStrokeStyle
Stroke style (eg solid, dashed)
@ PropertyCapStyle
Line cap style.
@ PropertyAngle
Symbol angle.
@ PropertySize
Symbol size.
@ PropertyJoinStyle
Line join style.
@ PropertyOpacity
Opacity.
@ PropertyCharacter
Character, eg for font marker symbol layers.
@ PropertyOffset
Symbol offset.
@ PropertyStrokeWidth
Stroke width.
@ PropertyFillColor
Fill color.
@ PropertyFontStyle
Font style.
@ PropertyHeight
Symbol height.
@ PropertyFontFamily
Font family.
@ PropertyName
Name, eg shape name for simple markers.
@ PropertyStrokeColor
Stroke color.
@ PropertyWidth
Symbol width.
static const bool SELECTION_IS_OPAQUE
Whether styles for selected features ignore symbol alpha.
virtual QSet< QString > usedAttributes(const QgsRenderContext &context) const
Returns the set of attributes referenced by the layer.
void copyDataDefinedProperties(QgsSymbolLayer *destLayer) const
Copies all data defined properties of this layer to another symbol layer.
void restoreOldDataDefinedProperties(const QVariantMap &stringMap)
Restores older data defined properties from string map.
virtual void prepareExpressions(const QgsSymbolRenderContext &context)
Prepares all data defined property expressions for evaluation.
virtual void setColor(const QColor &color)
Sets the "representative" color for the symbol layer.
virtual QColor color() const
Returns the "representative" color of the symbol layer.
void copyPaintEffect(QgsSymbolLayer *destLayer) const
Copies paint effect of this layer to another symbol layer.
QgsPropertyCollection mDataDefinedProperties
virtual bool hasDataDefinedProperties() const
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
QgsFields fields() const
Fields of the layer.
bool selected() const
Returns true if symbols should be rendered using the selected symbol coloring and style.
Qgis::SymbolRenderHints renderHints() const
Returns the rendering hint flags for the symbol.
QgsRenderContext & renderContext()
Returns a reference to the context's render context.
const QgsFeature * feature() const
Returns the current feature being rendered.
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for data defined symbology.
qreal opacity() const
Returns the opacity for the symbol.
Abstract base class for all rendered symbols.
Qgis::SymbolType type() const
Returns the symbol's type.
static Q_INVOKABLE QString encodeUnit(QgsUnitTypes::DistanceUnit unit)
Encodes a distance unit to a string.
static Q_INVOKABLE QgsUnitTypes::RenderUnit decodeRenderUnit(const QString &string, bool *ok=nullptr)
Decodes a render unit from a string.
RenderUnit
Rendering size units.
@ RenderUnknownUnit
Mixed or unknown units.
@ RenderMetersInMapUnits
Meters value as Map units.
@ RenderPercentage
Percentage of another measurement (e.g., canvas size, feature size)
@ RenderMillimeters
Millimeters.
@ RenderMapUnits
Map units.
double ANALYSIS_EXPORT angle(QgsPoint *p1, QgsPoint *p2, QgsPoint *p3, QgsPoint *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
QMap< QString, QString > QgsStringMap
QVector< QgsPointSequence > QgsRingSequence
QVector< QgsPoint > QgsPointSequence
#define QgsDebugMsgLevel(str, level)
Q_GUI_EXPORT int qt_defaultDpiX()
Q_GUI_EXPORT int qt_defaultDpiY()
#define DEFAULT_FONTMARKER_JOINSTYLE
#define DEFAULT_RASTERMARKER_ANGLE
#define DEFAULT_RASTERMARKER_SIZE
#define DEFAULT_SVGMARKER_ANGLE
#define DEFAULT_SIMPLEMARKER_JOINSTYLE
#define DEFAULT_FONTMARKER_CHR
#define DEFAULT_SIMPLEMARKER_BORDERCOLOR
#define DEFAULT_SIMPLEMARKER_SIZE
#define DEFAULT_SIMPLEMARKER_NAME
#define DEFAULT_SIMPLEMARKER_ANGLE
#define DEFAULT_SVGMARKER_SIZE
#define DEFAULT_FONTMARKER_FONT
#define DEFAULT_FONTMARKER_BORDERCOLOR
#define DEFAULT_FONTMARKER_ANGLE
#define DEFAULT_FONTMARKER_COLOR
#define DEFAULT_FONTMARKER_SIZE
#define DEFAULT_SIMPLEMARKER_COLOR
#define DEFAULT_SCALE_METHOD