31 #include <QSvgRenderer>
34 #include <QDomDocument>
35 #include <QDomElement>
42 static void _fixQPictureDPI( QPainter *p )
48 p->scale(
static_cast< double >(
qt_defaultDpiX() ) / p->device()->logicalDpiX(),
49 static_cast< double >(
qt_defaultDpiY() ) / p->device()->logicalDpiY() );
62 QList< Shape > shapes;
153 QTransform transform;
156 if ( !hasDataDefinedSize )
166 double half = scaledSize / 2.0;
167 transform.scale( half, half );
173 transform.rotate(
mAngle );
200 bool hasDataDefinedSize =
false;
201 double scaledSize =
calculateSize( context, hasDataDefinedSize );
203 bool hasDataDefinedRotation =
false;
209 bool createdNewPath =
false;
216 if ( exprVal.isValid() )
227 createdNewPath =
true;
236 QTransform transform;
239 transform.translate( point.x() +
offset.x(), point.y() +
offset.y() );
242 if ( hasDataDefinedSize || createdNewPath )
251 double half = s / 2.0;
252 transform.scale( half, half );
257 transform.rotate(
angle );
266 polygon = transform.map(
mPolygon );
270 path = transform.map(
mPath );
272 draw( context, symbol, polygon, path );
277 bool hasDataDefinedSize =
false;
278 double scaledSize =
calculateSize( context, hasDataDefinedSize );
280 bool hasDataDefinedRotation =
false;
287 QTransform transform;
290 transform.translate( point.x() +
offset.x(), point.y() +
offset.y() );
293 transform.rotate(
angle );
295 return transform.mapRect( QRectF( -scaledSize / 2.0,
305 QString cleaned = name.toLower().trimmed();
307 if ( cleaned == QLatin1String(
"square" ) || cleaned == QLatin1String(
"rectangle" ) )
309 else if ( cleaned == QLatin1String(
"square_with_corners" ) )
311 else if ( cleaned == QLatin1String(
"diamond" ) )
313 else if ( cleaned == QLatin1String(
"pentagon" ) )
315 else if ( cleaned == QLatin1String(
"hexagon" ) )
317 else if ( cleaned == QLatin1String(
"octagon" ) )
319 else if ( cleaned == QLatin1String(
"triangle" ) )
321 else if ( cleaned == QLatin1String(
"equilateral_triangle" ) )
323 else if ( cleaned == QLatin1String(
"star" ) || cleaned == QLatin1String(
"regular_star" ) )
325 else if ( cleaned == QLatin1String(
"arrow" ) )
327 else if ( cleaned == QLatin1String(
"circle" ) )
329 else if ( cleaned == QLatin1String(
"cross" ) )
331 else if ( cleaned == QLatin1String(
"cross_fill" ) )
333 else if ( cleaned == QLatin1String(
"cross2" ) || cleaned == QLatin1String(
"x" ) )
335 else if ( cleaned == QLatin1String(
"line" ) )
337 else if ( cleaned == QLatin1String(
"arrowhead" ) )
339 else if ( cleaned == QLatin1String(
"filled_arrowhead" ) )
341 else if ( cleaned == QLatin1String(
"semi_circle" ) )
343 else if ( cleaned == QLatin1String(
"third_circle" ) )
345 else if ( cleaned == QLatin1String(
"quarter_circle" ) )
347 else if ( cleaned == QLatin1String(
"quarter_square" ) )
349 else if ( cleaned == QLatin1String(
"half_square" ) )
351 else if ( cleaned == QLatin1String(
"diagonal_half_square" ) )
353 else if ( cleaned == QLatin1String(
"right_half_triangle" ) )
355 else if ( cleaned == QLatin1String(
"left_half_triangle" ) )
357 else if ( cleaned == QLatin1String(
"asterisk_fill" ) )
370 return QStringLiteral(
"square" );
372 return QStringLiteral(
"quarter_square" );
374 return QStringLiteral(
"half_square" );
376 return QStringLiteral(
"diagonal_half_square" );
378 return QStringLiteral(
"diamond" );
380 return QStringLiteral(
"pentagon" );
382 return QStringLiteral(
"hexagon" );
384 return QStringLiteral(
"octagon" );
386 return QStringLiteral(
"square_with_corners" );
388 return QStringLiteral(
"triangle" );
390 return QStringLiteral(
"equilateral_triangle" );
392 return QStringLiteral(
"left_half_triangle" );
394 return QStringLiteral(
"right_half_triangle" );
396 return QStringLiteral(
"star" );
398 return QStringLiteral(
"arrow" );
400 return QStringLiteral(
"filled_arrowhead" );
402 return QStringLiteral(
"cross_fill" );
404 return QStringLiteral(
"circle" );
406 return QStringLiteral(
"cross" );
408 return QStringLiteral(
"cross2" );
410 return QStringLiteral(
"line" );
412 return QStringLiteral(
"arrowhead" );
414 return QStringLiteral(
"semi_circle" );
416 return QStringLiteral(
"third_circle" );
418 return QStringLiteral(
"quarter_circle" );
420 return QStringLiteral(
"asterisk_fill" );
437 polygon = QPolygonF( QRectF( QPointF( -1, -1 ), QPointF( 1, 1 ) ) );
442 static constexpr
double VERTEX_OFFSET_FROM_ORIGIN = 0.6072;
444 polygon << QPointF( - VERTEX_OFFSET_FROM_ORIGIN, 1 )
445 << QPointF( VERTEX_OFFSET_FROM_ORIGIN, 1 )
446 << QPointF( 1, VERTEX_OFFSET_FROM_ORIGIN )
447 << QPointF( 1, -VERTEX_OFFSET_FROM_ORIGIN )
448 << QPointF( VERTEX_OFFSET_FROM_ORIGIN, -1 )
449 << QPointF( -VERTEX_OFFSET_FROM_ORIGIN, -1 )
450 << QPointF( -1, -VERTEX_OFFSET_FROM_ORIGIN )
451 << QPointF( -1, VERTEX_OFFSET_FROM_ORIGIN )
452 << QPointF( -VERTEX_OFFSET_FROM_ORIGIN, 1 );
457 polygon = QPolygonF( QRectF( QPointF( -1, -1 ), QPointF( 0, 0 ) ) );
461 polygon = QPolygonF( QRectF( QPointF( -1, -1 ), QPointF( 0, 1 ) ) );
465 polygon << QPointF( -1, -1 ) << QPointF( 1, 1 ) << QPointF( -1, 1 ) << QPointF( -1, -1 );
469 polygon << QPointF( -1, 0 ) << QPointF( 0, 1 )
470 << QPointF( 1, 0 ) << QPointF( 0, -1 ) << QPointF( -1, 0 );
480 polygon << QPointF( -0.9511, -0.3090 )
481 << QPointF( -0.5878, 0.8090 )
482 << QPointF( 0.5878, 0.8090 )
483 << QPointF( 0.9511, -0.3090 )
485 << QPointF( -0.9511, -0.3090 );
496 polygon << QPointF( -0.8660, -0.5 )
497 << QPointF( -0.8660, 0.5 )
499 << QPointF( 0.8660, 0.5 )
500 << QPointF( 0.8660, -0.5 )
502 << QPointF( -0.8660, -0.5 );
507 static constexpr
double VERTEX_OFFSET_FROM_ORIGIN = 1.0 / ( 1 + M_SQRT2 );
509 polygon << QPointF( - VERTEX_OFFSET_FROM_ORIGIN, 1 )
510 << QPointF( VERTEX_OFFSET_FROM_ORIGIN, 1 )
511 << QPointF( 1, VERTEX_OFFSET_FROM_ORIGIN )
512 << QPointF( 1, -VERTEX_OFFSET_FROM_ORIGIN )
513 << QPointF( VERTEX_OFFSET_FROM_ORIGIN, -1 )
514 << QPointF( -VERTEX_OFFSET_FROM_ORIGIN, -1 )
515 << QPointF( -1, -VERTEX_OFFSET_FROM_ORIGIN )
516 << QPointF( -1, VERTEX_OFFSET_FROM_ORIGIN )
517 << QPointF( -VERTEX_OFFSET_FROM_ORIGIN, 1 );
522 polygon << QPointF( -1, 1 ) << QPointF( 1, 1 ) << QPointF( 0, -1 ) << QPointF( -1, 1 );
530 polygon << QPointF( -0.8660, 0.5 )
531 << QPointF( 0.8660, 0.5 )
533 << QPointF( -0.8660, 0.5 );
537 polygon << QPointF( 0, 1 ) << QPointF( 1, 1 ) << QPointF( 0, -1 ) << QPointF( 0, 1 );
541 polygon << QPointF( -1, 1 ) << QPointF( 0, 1 ) << QPointF( 0, -1 ) << QPointF( -1, 1 );
546 double inner_r = std::cos(
DEG2RAD( 72.0 ) ) / std::cos(
DEG2RAD( 36.0 ) );
548 polygon << QPointF( inner_r * std::sin(
DEG2RAD( 324.0 ) ), - inner_r * std::cos(
DEG2RAD( 324.0 ) ) )
549 << QPointF( std::sin(
DEG2RAD( 288.0 ) ), - std::cos(
DEG2RAD( 288 ) ) )
550 << QPointF( inner_r * std::sin(
DEG2RAD( 252.0 ) ), - inner_r * std::cos(
DEG2RAD( 252.0 ) ) )
551 << QPointF( std::sin(
DEG2RAD( 216.0 ) ), - std::cos(
DEG2RAD( 216.0 ) ) )
552 << QPointF( 0, inner_r )
553 << QPointF( std::sin(
DEG2RAD( 144.0 ) ), - std::cos(
DEG2RAD( 144.0 ) ) )
554 << QPointF( inner_r * std::sin(
DEG2RAD( 108.0 ) ), - inner_r * std::cos(
DEG2RAD( 108.0 ) ) )
555 << QPointF( std::sin(
DEG2RAD( 72.0 ) ), - std::cos(
DEG2RAD( 72.0 ) ) )
556 << QPointF( inner_r * std::sin(
DEG2RAD( 36.0 ) ), - inner_r * std::cos(
DEG2RAD( 36.0 ) ) )
558 << QPointF( inner_r * std::sin(
DEG2RAD( 324.0 ) ), - inner_r * std::cos(
DEG2RAD( 324.0 ) ) );
563 polygon << QPointF( 0, -1 )
564 << QPointF( 0.5, -0.5 )
565 << QPointF( 0.25, -0.5 )
566 << QPointF( 0.25, 1 )
567 << QPointF( -0.25, 1 )
568 << QPointF( -0.25, -0.5 )
569 << QPointF( -0.5, -0.5 )
574 polygon << QPointF( 0, 0 ) << QPointF( -1, 1 ) << QPointF( -1, -1 ) << QPointF( 0, 0 );
578 polygon << QPointF( -1, -0.2 )
579 << QPointF( -1, -0.2 )
580 << QPointF( -1, 0.2 )
581 << QPointF( -0.2, 0.2 )
582 << QPointF( -0.2, 1 )
584 << QPointF( 0.2, 0.2 )
586 << QPointF( 1, -0.2 )
587 << QPointF( 0.2, -0.2 )
588 << QPointF( 0.2, -1 )
589 << QPointF( -0.2, -1 )
590 << QPointF( -0.2, -0.2 )
591 << QPointF( -1, -0.2 );
596 static constexpr
double THICKNESS = 0.3;
597 static constexpr
double HALF_THICKNESS = THICKNESS / 2.0;
598 static constexpr
double INTERSECTION_POINT = THICKNESS / M_SQRT2;
599 static constexpr
double DIAGONAL1 = M_SQRT1_2 - INTERSECTION_POINT * 0.5;
600 static constexpr
double DIAGONAL2 = M_SQRT1_2 + INTERSECTION_POINT * 0.5;
602 polygon << QPointF( -HALF_THICKNESS, -1 )
603 << QPointF( HALF_THICKNESS, -1 )
604 << QPointF( HALF_THICKNESS, -HALF_THICKNESS - INTERSECTION_POINT )
605 << QPointF( DIAGONAL1, -DIAGONAL2 )
606 << QPointF( DIAGONAL2, -DIAGONAL1 )
607 << QPointF( HALF_THICKNESS + INTERSECTION_POINT, -HALF_THICKNESS )
608 << QPointF( 1, -HALF_THICKNESS )
609 << QPointF( 1, HALF_THICKNESS )
610 << QPointF( HALF_THICKNESS + INTERSECTION_POINT, HALF_THICKNESS )
611 << QPointF( DIAGONAL2, DIAGONAL1 )
612 << QPointF( DIAGONAL1, DIAGONAL2 )
613 << QPointF( HALF_THICKNESS, HALF_THICKNESS + INTERSECTION_POINT )
614 << QPointF( HALF_THICKNESS, 1 )
615 << QPointF( -HALF_THICKNESS, 1 )
616 << QPointF( -HALF_THICKNESS, HALF_THICKNESS + INTERSECTION_POINT )
617 << QPointF( -DIAGONAL1, DIAGONAL2 )
618 << QPointF( -DIAGONAL2, DIAGONAL1 )
619 << QPointF( -HALF_THICKNESS - INTERSECTION_POINT, HALF_THICKNESS )
620 << QPointF( -1, HALF_THICKNESS )
621 << QPointF( -1, -HALF_THICKNESS )
622 << QPointF( -HALF_THICKNESS - INTERSECTION_POINT, -HALF_THICKNESS )
623 << QPointF( -DIAGONAL2, -DIAGONAL1 )
624 << QPointF( -DIAGONAL1, -DIAGONAL2 )
625 << QPointF( -HALF_THICKNESS, -HALF_THICKNESS - INTERSECTION_POINT )
626 << QPointF( -HALF_THICKNESS, -1 );
646 mPath = QPainterPath();
652 mPath.addEllipse( QRectF( -1, -1, 2, 2 ) );
656 mPath.arcTo( -1, -1, 2, 2, 0, 180 );
657 mPath.lineTo( 0, 0 );
661 mPath.arcTo( -1, -1, 2, 2, 90, 120 );
662 mPath.lineTo( 0, 0 );
666 mPath.arcTo( -1, -1, 2, 2, 90, 90 );
667 mPath.lineTo( 0, 0 );
671 mPath.moveTo( -1, 0 );
672 mPath.lineTo( 1, 0 );
673 mPath.moveTo( 0, -1 );
674 mPath.lineTo( 0, 1 );
678 mPath.moveTo( -1, -1 );
679 mPath.lineTo( 1, 1 );
680 mPath.moveTo( 1, -1 );
681 mPath.lineTo( -1, 1 );
685 mPath.moveTo( 0, -1 );
686 mPath.lineTo( 0, 1 );
690 mPath.moveTo( -1, -1 );
691 mPath.lineTo( 0, 0 );
692 mPath.lineTo( -1, 1 );
720 double scaledSize =
mSize;
724 if ( hasDataDefinedSize )
731 if ( hasDataDefinedSize && ok )
736 scaledSize = std::sqrt( scaledSize );
751 markerOffset( context, scaledSize, scaledSize, offsetX, offsetY );
752 offset = QPointF( offsetX, offsetY );
754 hasDataDefinedRotation =
false;
767 hasDataDefinedRotation =
true;
772 if ( hasDataDefinedRotation )
801 , mStrokeColor( strokeColor )
802 , mPenJoinStyle( penJoinStyle )
817 if ( props.contains( QStringLiteral(
"name" ) ) )
821 if ( props.contains( QStringLiteral(
"color" ) ) )
823 if ( props.contains( QStringLiteral(
"color_border" ) ) )
828 else if ( props.contains( QStringLiteral(
"outline_color" ) ) )
832 else if ( props.contains( QStringLiteral(
"line_color" ) ) )
836 if ( props.contains( QStringLiteral(
"joinstyle" ) ) )
840 if ( props.contains( QStringLiteral(
"size" ) ) )
841 size = props[QStringLiteral(
"size" )].toDouble();
842 if ( props.contains( QStringLiteral(
"angle" ) ) )
843 angle = props[QStringLiteral(
"angle" )].toDouble();
844 if ( props.contains( QStringLiteral(
"scale_method" ) ) )
848 if ( props.contains( QStringLiteral(
"offset" ) ) )
850 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
852 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
854 if ( props.contains( QStringLiteral(
"size_unit" ) ) )
856 if ( props.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
859 if ( props.contains( QStringLiteral(
"outline_style" ) ) )
863 else if ( props.contains( QStringLiteral(
"line_style" ) ) )
867 if ( props.contains( QStringLiteral(
"outline_width" ) ) )
869 m->
setStrokeWidth( props[QStringLiteral(
"outline_width" )].toDouble() );
871 else if ( props.contains( QStringLiteral(
"line_width" ) ) )
873 m->
setStrokeWidth( props[QStringLiteral(
"line_width" )].toDouble() );
875 if ( props.contains( QStringLiteral(
"outline_width_unit" ) ) )
879 if ( props.contains( QStringLiteral(
"line_width_unit" ) ) )
883 if ( props.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
888 if ( props.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
892 if ( props.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
905 return QStringLiteral(
"SimpleMarker" );
912 QColor brushColor =
mColor;
918 mBrush = QBrush( brushColor );
919 mPen = QPen( penColor );
928 selBrushColor.setAlphaF( context.
opacity() );
929 selPenColor.setAlphaF( context.
opacity() );
948 mCachedOpacity = context.
opacity();
954 mSelPen.setColor( selBrushColor );
986 scaledSize = ( std::abs( std::sin(
mAngle * M_PI / 180 ) ) + std::abs( std::cos(
mAngle * M_PI / 180 ) ) ) * scaledSize;
989 double pw =
static_cast< int >( std::round( ( (
qgsDoubleNear(
mPen.widthF(), 0.0 ) ? 1 :
mPen.widthF() * 4 ) + 1 ) ) ) / 2 * 2;
990 int imageSize = (
static_cast< int >( scaledSize ) + pw ) / 2 * 2 + 1;
991 double center = imageSize / 2.0;
997 mCache = QImage( QSize( imageSize, imageSize ), QImage::Format_ARGB32_Premultiplied );
1004 p.setRenderHint( QPainter::Antialiasing );
1005 p.setBrush( needsBrush ?
mBrush : Qt::NoBrush );
1007 p.translate( QPointF( center, center ) );
1015 mSelCache = QImage( QSize( imageSize, imageSize ), QImage::Format_ARGB32_Premultiplied );
1019 p.setRenderHint( QPainter::Antialiasing );
1020 p.setBrush( needsBrush ?
mSelBrush : Qt::NoBrush );
1022 p.translate( QPointF( center, center ) );
1033 p.setRenderHint( QPainter::Antialiasing );
1034 p.fillRect( 0, 0, imageSize, imageSize, selColor );
1035 p.setBrush( needsBrush ?
mBrush : Qt::NoBrush );
1037 p.translate( QPointF( center, center ) );
1056 QColor brushColor =
mColor;
1057 brushColor.setAlphaF( brushColor.alphaF() * context.
opacity() );
1058 mBrush.setColor( brushColor );
1061 penColor.setAlphaF( penColor.alphaF() * context.
opacity() );
1062 mPen.setColor( penColor );
1071 c.setAlphaF(
c.alphaF() * context.
opacity() );
1081 c.setAlphaF(
c.alphaF() * context.
opacity() );
1123 p->setBrush( Qt::NoBrush );
1127 if ( !polygon.isEmpty() )
1128 p->drawPolygon( polygon );
1130 p->drawPath( path );
1147 double s = img.width();
1149 bool hasDataDefinedSize =
false;
1150 double scaledSize =
calculateSize( context, hasDataDefinedSize );
1152 bool hasDataDefinedRotation =
false;
1157 p->drawImage( QRectF( point.x() - s / 2.0 +
offset.x(),
1158 point.y() - s / 2.0 +
offset.y(),
1173 map[QStringLiteral(
"size" )] = QString::number(
mSize );
1176 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
1182 map[QStringLiteral(
"outline_width" )] = QString::number(
mStrokeWidth );
1213 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
1214 element.appendChild( graphicElem );
1223 double angle = props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toDouble( &ok );
1226 angleFunc = QStringLiteral(
"%1 + %2" ).arg( props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toString() ).arg(
mAngle );
1241 Q_UNUSED( mmScaleFactor )
1242 Q_UNUSED( mapUnitScaleFactor )
1244 QString ogrType =
"3";
1245 if ( mName ==
"square" )
1249 else if ( mName ==
"triangle" )
1253 else if ( mName ==
"star" )
1257 else if ( mName ==
"circle" )
1261 else if ( mName ==
"cross" )
1265 else if ( mName ==
"x" || mName ==
"cross2" )
1269 else if ( mName ==
"line" )
1275 ogrString.append(
"SYMBOL(" );
1276 ogrString.append(
"id:" );
1277 ogrString.append(
'\"' );
1278 ogrString.append(
"ogr-sym-" );
1279 ogrString.append( ogrType );
1280 ogrString.append(
'\"' );
1281 ogrString.append(
",c:" );
1282 ogrString.append(
mColor.name() );
1283 ogrString.append(
",o:" );
1285 ogrString.append( QString(
",s:%1mm" ).arg(
mSize ) );
1286 ogrString.append(
')' );
1291 ogrString.append(
"PEN(" );
1292 ogrString.append(
"c:" );
1293 ogrString.append(
mColor.name() );
1294 ogrString.append(
",w:" );
1295 ogrString.append( QString::number(
mSize ) );
1296 ogrString.append(
"mm" );
1297 ogrString.append(
")" );
1305 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
1306 if ( graphicElem.isNull() )
1309 QString name = QStringLiteral(
"square" );
1322 double d = angleFunc.toDouble( &ok );
1332 QString uom = element.attribute( QStringLiteral(
"uom" ) );
1358 p->drawPath(
mPath );
1371 if ( hasDataDefinedSize )
1392 size *= mmMapUnitScaleFactor;
1399 double halfSize =
size / 2.0;
1416 QColor pc =
mPen.color();
1417 QColor bc =
mBrush.color();
1437 QPointF off( offsetX, offsetY );
1466 t.translate( shift.x() + off.x(), shift.y() - off.y() );
1474 t.scale( halfSize, -halfSize );
1476 polygon = t.map( polygon );
1479 p.reserve( polygon.size() );
1480 for (
int i = 0; i < polygon.size(); i++ )
1485 if (
mBrush.style() != Qt::NoBrush )
1487 if (
mPen.style() != Qt::NoPen )
1492 shift += QPointF( off.x(), -off.y() );
1493 if (
mBrush.style() != Qt::NoBrush )
1495 if (
mPen.style() != Qt::NoPen )
1500 QPointF pt1 = t.map( QPointF( 0, -halfSize ) );
1501 QPointF pt2 = t.map( QPointF( 0, halfSize ) );
1503 if (
mPen.style() != Qt::NoPen )
1508 if (
mPen.style() != Qt::NoPen )
1510 QPointF pt1 = t.map( QPointF( -halfSize, 0 ) );
1511 QPointF pt2 = t.map( QPointF( halfSize, 0 ) );
1512 QPointF pt3 = t.map( QPointF( 0, -halfSize ) );
1513 QPointF pt4 = t.map( QPointF( 0, halfSize ) );
1521 if (
mPen.style() != Qt::NoPen )
1523 QPointF pt1 = t.map( QPointF( -halfSize, -halfSize ) );
1524 QPointF pt2 = t.map( QPointF( halfSize, halfSize ) );
1525 QPointF pt3 = t.map( QPointF( halfSize, -halfSize ) );
1526 QPointF pt4 = t.map( QPointF( -halfSize, halfSize ) );
1534 if (
mPen.style() != Qt::NoPen )
1536 QPointF pt1 = t.map( QPointF( -halfSize, halfSize ) );
1537 QPointF pt2 = t.map( QPointF( 0, 0 ) );
1538 QPointF pt3 = t.map( QPointF( -halfSize, -halfSize ) );
1624 symbolBounds.adjust( -penWidth / 2.0, -penWidth / 2.0,
1625 penWidth / 2.0, penWidth / 2.0 );
1627 return symbolBounds;
1674 if ( props.contains( QStringLiteral(
"name" ) ) )
1675 name = props[QStringLiteral(
"name" )].toString();
1676 if ( props.contains( QStringLiteral(
"size" ) ) )
1677 size = props[QStringLiteral(
"size" )].toDouble();
1678 if ( props.contains( QStringLiteral(
"angle" ) ) )
1679 angle = props[QStringLiteral(
"angle" )].toDouble();
1680 if ( props.contains( QStringLiteral(
"scale_method" ) ) )
1684 if ( props.contains( QStringLiteral(
"offset" ) ) )
1686 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
1688 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
1690 if ( props.contains( QStringLiteral(
"size_unit" ) ) )
1692 if ( props.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
1694 if ( props.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
1698 if ( props.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
1712 return QStringLiteral(
"FilledMarker" );
1737 map[QStringLiteral(
"size" )] = QString::number(
mSize );
1740 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
1796 attr.unite( mFill->usedAttributes( context ) );
1804 if ( mFill && mFill->hasDataDefinedProperties() )
1813 mFill->setColor(
c );
1818 return mFill ? mFill->color() :
mColor;
1825 || ( mFill && mFill->usesMapUnits() );
1839 const double prevOpacity = mFill->opacity();
1840 mFill->setOpacity( mFill->opacity() * context.
opacity() );
1844 p->setBrush( Qt::red );
1848 p->setBrush( Qt::NoBrush );
1850 p->setPen( Qt::black );
1852 if ( !polygon.isEmpty() )
1858 QPolygonF poly = path.toFillPolygon();
1862 mFill->setOpacity( prevOpacity );
1877 mColor = QColor( 35, 35, 35 );
1890 if ( props.contains( QStringLiteral(
"name" ) ) )
1891 name = props[QStringLiteral(
"name" )].toString();
1892 if ( props.contains( QStringLiteral(
"size" ) ) )
1893 size = props[QStringLiteral(
"size" )].toDouble();
1894 if ( props.contains( QStringLiteral(
"angle" ) ) )
1895 angle = props[QStringLiteral(
"angle" )].toDouble();
1896 if ( props.contains( QStringLiteral(
"scale_method" ) ) )
1901 if ( props.contains( QStringLiteral(
"size_unit" ) ) )
1903 if ( props.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
1905 if ( props.contains( QStringLiteral(
"fixedAspectRatio" ) ) )
1907 if ( props.contains( QStringLiteral(
"offset" ) ) )
1909 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
1911 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
1913 if ( props.contains( QStringLiteral(
"fill" ) ) )
1918 else if ( props.contains( QStringLiteral(
"color" ) ) )
1922 if ( props.contains( QStringLiteral(
"outline" ) ) )
1927 else if ( props.contains( QStringLiteral(
"outline_color" ) ) )
1931 else if ( props.contains( QStringLiteral(
"line_color" ) ) )
1936 if ( props.contains( QStringLiteral(
"outline-width" ) ) )
1939 m->
setStrokeWidth( props[QStringLiteral(
"outline-width" )].toDouble() );
1941 else if ( props.contains( QStringLiteral(
"outline_width" ) ) )
1943 m->
setStrokeWidth( props[QStringLiteral(
"outline_width" )].toDouble() );
1945 else if ( props.contains( QStringLiteral(
"line_width" ) ) )
1947 m->
setStrokeWidth( props[QStringLiteral(
"line_width" )].toDouble() );
1950 if ( props.contains( QStringLiteral(
"outline_width_unit" ) ) )
1954 else if ( props.contains( QStringLiteral(
"line_width_unit" ) ) )
1958 if ( props.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
1961 if ( props.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
1965 if ( props.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
1974 if ( props.contains( QStringLiteral(
"parameters" ) ) )
1976 const QVariantMap
parameters = props[QStringLiteral(
"parameters" )].toMap();
1977 QMap<QString, QgsProperty> parametersProperties;
1978 QVariantMap::const_iterator it =
parameters.constBegin();
1983 parametersProperties.insert( it.key(), property );
1994 QVariantMap::iterator it =
properties.find( QStringLiteral(
"name" ) );
2013 QColor defaultFillColor, defaultStrokeColor;
2015 bool hasFillOpacityParam =
false, hasStrokeParam =
false, hasStrokeWidthParam =
false, hasStrokeOpacityParam =
false;
2016 bool hasDefaultFillColor =
false, hasDefaultFillOpacity =
false, hasDefaultStrokeColor =
false, hasDefaultStrokeWidth =
false, hasDefaultStrokeOpacity =
false;
2018 hasFillOpacityParam, hasDefaultFillOpacity, fillOpacity,
2019 hasStrokeParam, hasDefaultStrokeColor, defaultStrokeColor,
2020 hasStrokeWidthParam, hasDefaultStrokeWidth,
strokeWidth,
2021 hasStrokeOpacityParam, hasDefaultStrokeOpacity, strokeOpacity );
2023 double newFillOpacity = hasFillOpacityParam ?
fillColor().alphaF() : 1.0;
2024 double newStrokeOpacity = hasStrokeOpacityParam ?
strokeColor().alphaF() : 1.0;
2026 if ( hasDefaultFillColor )
2028 defaultFillColor.setAlphaF( newFillOpacity );
2031 if ( hasDefaultFillOpacity )
2034 c.setAlphaF( fillOpacity );
2037 if ( hasDefaultStrokeColor )
2039 defaultStrokeColor.setAlphaF( newStrokeOpacity );
2042 if ( hasDefaultStrokeWidth )
2046 if ( hasDefaultStrokeOpacity )
2049 c.setAlphaF( strokeOpacity );
2063 double widthScaleFactor = 3.465;
2066 mDefaultAspectRatio = svgViewbox.isValid() ? svgViewbox.height() / svgViewbox.width() : 0.0;
2074 if ( aPreservedAspectRatio && !par )
2078 else if ( !aPreservedAspectRatio && par )
2093 return QStringLiteral(
"SvgMarker" );
2113 bool hasDataDefinedSize =
false;
2114 double scaledWidth = calculateSize( context, hasDataDefinedSize );
2118 if (
static_cast< int >( width ) < 1 || 10000.0 < width )
2125 bool hasDataDefinedAspectRatio =
false;
2169 scaledHeight = svgViewbox.isValid() ? scaledWidth * svgViewbox.height() / svgViewbox.width() : scaledWidth;
2173 QPointF outputOffset;
2175 calculateOffsetAndRotation( context, scaledWidth, scaledHeight, outputOffset,
angle );
2177 p->translate( point + outputOffset );
2183 bool fitsInCache =
true;
2184 bool usePict =
true;
2191 if ( fitsInCache && img.width() > 1 )
2201 QImage transparentImage = img.copy();
2203 p->drawImage( -transparentImage.width() / 2.0, -transparentImage.height() / 2.0, transparentImage );
2207 p->drawImage( -img.width() / 2.0, -img.height() / 2.0, img );
2212 if ( usePict || !fitsInCache )
2214 p->setOpacity( context.
opacity() );
2218 if ( pct.width() > 1 )
2221 _fixQPictureDPI( p );
2222 p->drawPicture( 0, 0, pct );
2230 double QgsSvgMarkerSymbolLayer::calculateSize(
QgsSymbolRenderContext &context,
bool &hasDataDefinedSize )
const
2232 double scaledSize =
mSize;
2236 if ( hasDataDefinedSize )
2244 if ( hasDataDefinedSize )
2251 if ( hasDataDefinedSize && ok )
2256 scaledSize = std::sqrt( scaledSize );
2269 if ( !hasDataDefinedAspectRatio )
2279 double defaultHeight =
mSize * scaledAspectRatio;
2280 scaledAspectRatio = defaultHeight / scaledSize;
2283 double scaledHeight = scaledSize * scaledAspectRatio;
2290 if ( hasDataDefinedAspectRatio && ok )
2295 scaledHeight = sqrt( scaledHeight );
2302 scaledAspectRatio = scaledHeight / scaledSize;
2304 return scaledAspectRatio;
2307 void QgsSvgMarkerSymbolLayer::calculateOffsetAndRotation(
QgsSymbolRenderContext &context,
double scaledWidth,
double scaledHeight, QPointF &offset,
double &
angle )
const
2312 markerOffset( context, scaledWidth, scaledHeight, offsetX, offsetY );
2313 offset = QPointF( offsetX, offsetY );
2323 if ( hasDataDefinedRotation )
2349 map[QStringLiteral(
"name" )] =
mPath;
2350 map[QStringLiteral(
"size" )] = QString::number(
mSize );
2353 map[QStringLiteral(
"fixedAspectRatio" )] = QString::number(
mFixedAspectRatio );
2354 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
2361 map[QStringLiteral(
"outline_width" )] = QString::number(
mStrokeWidth );
2368 QMap<QString, QgsProperty>::const_iterator it =
mParameters.constBegin();
2370 parameters.insert( it.key(), it.value().toVariant() );
2371 map[QStringLiteral(
"parameters" )] =
parameters;
2440 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
2441 element.appendChild( graphicElem );
2451 double angle = props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toDouble( &ok );
2454 angleFunc = QStringLiteral(
"%1 + %2" ).arg( props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toString() ).arg(
mAngle );
2472 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
2473 if ( graphicElem.isNull() )
2476 QString
path, mimeType;
2483 QString uom = element.attribute( QStringLiteral(
"uom" ) );
2486 if ( mimeType != QLatin1String(
"image/svg+xml" ) )
2494 double d = angleFunc.toDouble( &ok );
2520 if ( hasDataDefinedSize )
2526 if ( hasDataDefinedSize && ok )
2540 size *= mmMapUnitScaleFactor;
2554 double offsetX =
offset.x();
2555 double offsetY =
offset.y();
2557 QPointF outputOffset( offsetX, offsetY );
2607 QSvgRenderer r( svgContent );
2614 QSizeF outSize( r.defaultSize() );
2615 outSize.scale(
size,
size, Qt::KeepAspectRatio );
2621 p.translate( r.defaultSize().width() / 2.0, r.defaultSize().height() / 2.0 );
2623 p.translate( -r.defaultSize().width() / 2.0, -r.defaultSize().height() / 2.0 );
2625 pd.
setShift( shift + QPointF( outputOffset.x(), -outputOffset.y() ) );
2626 pd.
setOutputSize( QRectF( -outSize.width() / 2.0, -outSize.height() / 2.0, outSize.width(), outSize.height() ) );
2635 bool hasDataDefinedSize =
false;
2636 double scaledWidth = calculateSize( context, hasDataDefinedSize );
2638 bool hasDataDefinedAspectRatio =
false;
2646 if (
static_cast< int >( scaledWidth ) < 1 || 10000.0 < scaledWidth )
2651 QPointF outputOffset;
2653 calculateOffsetAndRotation( context, scaledWidth, scaledHeight, outputOffset,
angle );
2692 scaledHeight = svgViewbox.isValid() ? scaledWidth * svgViewbox.height() / svgViewbox.width() : scaledWidth;
2698 transform.translate( point.x() + outputOffset.x(), point.y() + outputOffset.y() );
2701 transform.rotate(
angle );
2706 QRectF symbolBounds = transform.mapRect( QRectF( -scaledWidth / 2.0,
2707 -scaledHeight / 2.0,
2715 return symbolBounds;
2738 if ( props.contains( QStringLiteral(
"imageFile" ) ) )
2739 path = props[QStringLiteral(
"imageFile" )].toString();
2740 if ( props.contains( QStringLiteral(
"size" ) ) )
2741 size = props[QStringLiteral(
"size" )].toDouble();
2742 if ( props.contains( QStringLiteral(
"angle" ) ) )
2743 angle = props[QStringLiteral(
"angle" )].toDouble();
2744 if ( props.contains( QStringLiteral(
"scale_method" ) ) )
2749 if ( props.contains( QStringLiteral(
"alpha" ) ) )
2751 m->
setOpacity( props[QStringLiteral(
"alpha" )].toDouble() );
2754 if ( props.contains( QStringLiteral(
"size_unit" ) ) )
2756 if ( props.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
2758 if ( props.contains( QStringLiteral(
"fixedAspectRatio" ) ) )
2761 if ( props.contains( QStringLiteral(
"offset" ) ) )
2763 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
2765 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
2768 if ( props.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
2772 if ( props.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
2785 QVariantMap::iterator it =
properties.find( QStringLiteral(
"name" ) );
2786 if ( it !=
properties.end() && it.value().type() == QVariant::String )
2804 if ( aPreservedAspectRatio && !par )
2808 else if ( !aPreservedAspectRatio && par )
2827 return QStringLiteral(
"RasterMarker" );
2843 if (
path.isEmpty() )
2847 double height = 0.0;
2849 bool hasDataDefinedSize =
false;
2850 double scaledSize = calculateSize( context, hasDataDefinedSize );
2852 bool hasDataDefinedAspectRatio =
false;
2855 QPointF outputOffset;
2862 if (
size.isEmpty() )
2865 width = ( scaledSize *
static_cast< double >(
size.width() ) ) / 100.0;
2866 height = ( scaledSize *
static_cast< double >(
size.height() ) ) / 100.0;
2869 if (
static_cast< int >( width ) < 1 || 10000.0 < width ||
static_cast< int >( height ) < 1 || 10000.0 < height )
2872 calculateOffsetAndRotation( context, width, height, outputOffset,
angle );
2882 if ( !
size.isNull() &&
size.isValid() &&
size.width() > 0 )
2884 height = width * (
static_cast< double >(
size.height() ) /
static_cast< double >(
size.width() ) );
2889 if (
static_cast< int >( width ) < 1 || 10000.0 < width )
2892 calculateOffsetAndRotation( context, scaledSize, scaledSize * ( height / width ), outputOffset,
angle );
2896 p->translate( point + outputOffset );
2912 if ( !img.isNull() )
2917 p->drawImage( -img.width() / 2.0, -img.height() / 2.0, img );
2921 double QgsRasterMarkerSymbolLayer::calculateSize(
QgsSymbolRenderContext &context,
bool &hasDataDefinedSize )
const
2923 double scaledSize =
mSize;
2927 if ( hasDataDefinedSize )
2935 if ( hasDataDefinedSize )
2942 if ( hasDataDefinedSize && ok )
2947 scaledSize = std::sqrt( scaledSize );
2960 if ( !hasDataDefinedAspectRatio )
2970 double defaultHeight =
mSize * scaledAspectRatio;
2971 scaledAspectRatio = defaultHeight / scaledSize;
2974 double scaledHeight = scaledSize * scaledAspectRatio;
2981 if ( hasDataDefinedAspectRatio && ok )
2986 scaledHeight = sqrt( scaledHeight );
2993 scaledAspectRatio = scaledHeight / scaledSize;
2995 return scaledAspectRatio;
2998 void QgsRasterMarkerSymbolLayer::calculateOffsetAndRotation(
QgsSymbolRenderContext &context,
double scaledWidth,
double scaledHeight, QPointF &offset,
double &
angle )
const
3003 markerOffset( context, scaledWidth, scaledHeight, offsetX, offsetY );
3004 offset = QPointF( offsetX, offsetY );
3014 if ( hasDataDefinedRotation )
3035 map[QStringLiteral(
"imageFile" )] =
mPath;
3036 map[QStringLiteral(
"size" )] = QString::number(
mSize );
3039 map[QStringLiteral(
"fixedAspectRatio" )] = QString::number(
mFixedAspectRatio );
3040 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
3041 map[QStringLiteral(
"alpha" )] = QString::number(
mOpacity );
3086 bool hasDataDefinedSize =
false;
3087 double scaledSize = calculateSize( context, hasDataDefinedSize );
3089 bool hasDataDefinedAspectRatio =
false;
3094 if (
static_cast< int >( scaledSize ) < 1 || 10000.0 < scaledSize )
3099 QPointF outputOffset;
3101 calculateOffsetAndRotation( context, scaledSize, scaledSize * ( height / width ), outputOffset,
angle );
3106 transform.translate( point.x() + outputOffset.x(), point.y() + outputOffset.y() );
3109 transform.rotate(
angle );
3111 QRectF symbolBounds = transform.mapRect( QRectF( -width / 2.0,
3116 return symbolBounds;
3128 mOrigSize = pointSize;
3147 if ( props.contains( QStringLiteral(
"font" ) ) )
3148 fontFamily = props[QStringLiteral(
"font" )].toString();
3149 if ( props.contains( QStringLiteral(
"chr" ) ) && props[QStringLiteral(
"chr" )].toString().length() > 0 )
3150 string = props[QStringLiteral(
"chr" )].toString();
3151 if ( props.contains( QStringLiteral(
"size" ) ) )
3152 pointSize = props[QStringLiteral(
"size" )].toDouble();
3153 if ( props.contains( QStringLiteral(
"color" ) ) )
3155 if ( props.contains( QStringLiteral(
"angle" ) ) )
3156 angle = props[QStringLiteral(
"angle" )].toDouble();
3160 if ( props.contains( QStringLiteral(
"font_style" ) ) )
3161 m->
setFontStyle( props[QStringLiteral(
"font_style" )].toString() );
3162 if ( props.contains( QStringLiteral(
"outline_color" ) ) )
3164 if ( props.contains( QStringLiteral(
"outline_width" ) ) )
3165 m->
setStrokeWidth( props[QStringLiteral(
"outline_width" )].toDouble() );
3166 if ( props.contains( QStringLiteral(
"offset" ) ) )
3168 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
3170 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
3172 if ( props.contains( QStringLiteral(
"size_unit" ) ) )
3174 if ( props.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
3176 if ( props.contains( QStringLiteral(
"outline_width_unit" ) ) )
3178 if ( props.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
3180 if ( props.contains( QStringLiteral(
"joinstyle" ) ) )
3182 if ( props.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
3184 if ( props.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
3194 return QStringLiteral(
"FontMarker" );
3199 QColor brushColor =
mColor;
3200 QColor penColor = mStrokeColor;
3202 brushColor.setAlphaF(
mColor.alphaF() * context.
opacity() );
3203 penColor.setAlphaF( mStrokeColor.alphaF() * context.
opacity() );
3205 mBrush = QBrush( brushColor );
3206 mPen = QPen( penColor );
3207 mPen.setJoinStyle( mPenJoinStyle );
3210 mFont = QFont( mFontFamily );
3211 if ( !mFontStyle.isEmpty() )
3220 mFont.setPixelSize( std::max( 2,
static_cast< int >( std::round( sizePixels ) ) ) );
3221 mFontMetrics.reset(
new QFontMetrics( mFont ) );
3222 #if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
3223 mChrWidth = mFontMetrics->width( mString );
3225 mChrWidth = mFontMetrics->horizontalAdvance( mString );
3227 mChrOffset = QPointF( mChrWidth / 2.0, -mFontMetrics->ascent() / 2.0 );
3234 if ( mUseCachedPath )
3236 QPointF chrOffset = mChrOffset;
3238 QString charToRender = characterToRender( context, chrOffset, chrWidth );
3239 mCachedPath = QPainterPath();
3240 mCachedPath.addText( -chrOffset.x(), -chrOffset.y(), mFont, charToRender );
3249 QString QgsFontMarkerSymbolLayer::characterToRender(
QgsSymbolRenderContext &context, QPointF &charOffset,
double &charWidth )
3251 charOffset = mChrOffset;
3252 QString stringToRender = mString;
3257 if ( stringToRender != mString )
3259 #if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
3260 charWidth = mFontMetrics->width( stringToRender );
3262 charWidth = mFontMetrics->horizontalAdvance( stringToRender );
3264 charOffset = QPointF( charWidth / 2.0, -mFontMetrics->ascent() / 2.0 );
3267 return stringToRender;
3272 bool &hasDataDefinedRotation,
3274 double &
angle )
const
3279 markerOffset( context, scaledSize, scaledSize, offsetX, offsetY );
3280 offset = QPointF( offsetX, offsetY );
3296 if ( hasDataDefinedRotation )
3320 double scaledSize =
mSize;
3324 if ( hasDataDefinedSize )
3330 if ( hasDataDefinedSize && ok )
3335 scaledSize = std::sqrt( scaledSize );
3347 if ( !p || !mNonZeroFontSize )
3350 QTransform transform;
3353 QColor brushColor =
mColor;
3362 brushColor.setAlphaF( brushColor.alphaF() * context.
opacity() );
3364 mBrush.setColor( brushColor );
3366 QColor penColor = mStrokeColor;
3372 penColor.setAlphaF( penColor.alphaF() * context.
opacity() );
3396 p->setBrush( mBrush );
3399 mPen.setColor( penColor );
3400 mPen.setWidthF( penWidth );
3405 p->setPen( Qt::NoPen );
3412 mFont.setFamily( ok ?
fontFamily : mFontFamily );
3422 mFontMetrics.reset(
new QFontMetrics( mFont ) );
3425 QPointF chrOffset = mChrOffset;
3427 QString charToRender = characterToRender( context, chrOffset, chrWidth );
3429 double sizeToRender = calculateSize( context );
3431 bool hasDataDefinedRotation =
false;
3434 calculateOffsetAndRotation( context, sizeToRender, hasDataDefinedRotation,
offset,
angle );
3436 p->translate( point.x() +
offset.x(), point.y() +
offset.y() );
3439 transform.rotate(
angle );
3443 double s = sizeToRender / mOrigSize;
3444 transform.scale( s, s );
3447 if ( mUseCachedPath )
3449 p->drawPath( transform.map( mCachedPath ) );
3454 path.addText( -chrOffset.x(), -chrOffset.y(), mFont, charToRender );
3455 p->drawPath( transform.map( path ) );
3462 props[QStringLiteral(
"font" )] = mFontFamily;
3463 props[QStringLiteral(
"font_style" )] = mFontStyle;
3464 props[QStringLiteral(
"chr" )] = mString;
3465 props[QStringLiteral(
"size" )] = QString::number(
mSize );
3470 props[QStringLiteral(
"outline_width" )] = QString::number( mStrokeWidth );
3474 props[QStringLiteral(
"angle" )] = QString::number(
mAngle );
3507 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
3508 element.appendChild( graphicElem );
3510 QString fontPath = QStringLiteral(
"ttf://%1" ).arg( mFontFamily );
3511 int markIndex = !mString.isEmpty() ? mString.at( 0 ).unicode() : 0;
3518 double angle = props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toDouble( &ok );
3521 angleFunc = QStringLiteral(
"%1 + %2" ).arg( props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toString() ).arg(
mAngle );
3543 QPointF chrOffset = mChrOffset;
3544 double chrWidth = mChrWidth;
3546 ( void )characterToRender( context, chrOffset, chrWidth );
3548 if ( !mFontMetrics )
3549 mFontMetrics.reset(
new QFontMetrics( mFont ) );
3551 double scaledSize = calculateSize( context );
3554 chrWidth *= scaledSize / mOrigSize;
3557 bool hasDataDefinedRotation =
false;
3560 calculateOffsetAndRotation( context, scaledSize, hasDataDefinedRotation,
offset,
angle );
3566 transform.translate( point.x() +
offset.x(), point.y() +
offset.y() );
3569 transform.rotate(
angle );
3571 QRectF symbolBounds = transform.mapRect( QRectF( -chrWidth / 2.0,
3575 return symbolBounds;
3582 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
3583 if ( graphicElem.isNull() )
3586 QString name, format;
3594 if ( !name.startsWith( QLatin1String(
"ttf://" ) ) || format != QLatin1String(
"ttf" ) )
3604 double d = angleFunc.toDouble( &ok );
3612 QString uom = element.attribute( QStringLiteral(
"uom" ) );
3627 QMap<QString, QgsProperty>::iterator it =
mParameters.begin();
3639 QMap<QString, QgsProperty>::const_iterator it =
mParameters.constBegin();
3642 attrs.unite( it.value().referencedFields( context.
expressionContext(),
true ) );
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 id, geometry and a list of field/values...
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
The fill color.
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(QgsSimpleMarkerSymbolLayerBase::Shape shape=Circle, double size=DEFAULT_SIMPLEMARKER_SIZE, double angle=DEFAULT_SIMPLEMARKER_ANGLE, QgsSymbol::ScaleMethod scaleMethod=DEFAULT_SCALE_METHOD)
Constructor for QgsFilledMarkerSymbolLayer.
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
The fill color.
QString layerType() const override
Returns a string that represents this layer type.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsFilledMarkerSymbolLayer.
void setStrokeColor(const QColor &color) override
Set stroke color.
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.
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 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, 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)
Alter the hue or saturation of a QImage.
Perform transforms between map coordinates and device coordinates.
double mapUnitsPerPixel() const
Returns current map units per pixel.
double mapRotation() const
Returns 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.
QgsSymbol::ScaleMethod scaleMethod() const
Returns the method to use for scaling the marker's size.
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.
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.
QgsSymbol::ScaleMethod mScaleMethod
Marker size scaling method.
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.
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.
A store for object properties.
bool loadVariant(const QVariant &property)
Loads this property from a QVariantMap, wrapped in a QVariant.
Raster marker symbol layer class.
double mFixedAspectRatio
The marker fixed aspect ratio.
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.
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.
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.
QgsRasterMarkerSymbolLayer(const QString &path=QString(), double size=DEFAULT_SVGMARKER_SIZE, double angle=DEFAULT_SVGMARKER_ANGLE, QgsSymbol::ScaleMethod scaleMethod=DEFAULT_SCALE_METHOD)
Constructs raster marker symbol layer with picture from given absolute path to a raster image file.
double opacity() const
Returns the marker opacity.
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 ...
bool forceVectorOutput() const
Returns true if rendering operations should use vector operations instead of any faster raster shortc...
QColor selectionColor() const
Returns the color to use when rendering selected features.
@ RenderBlocking
Render and load remote sources in the same thread to ensure rendering remote sources (svg and images)...
@ RenderSymbolPreview
The render is for a symbol preview only and map based properties may not be available,...
Flags flags() const
Returns combination of flags used for rendering.
double convertToPainterUnits(double size, QgsUnitTypes::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale()) const
Converts a size from the specified units to painter units (pixels).
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.
Shape mShape
Symbol shape.
void calculateOffsetAndRotation(QgsSymbolRenderContext &context, double scaledSize, bool &hasDataDefinedRotation, QPointF &offset, double &angle) const
Calculates the marker offset and rotation.
bool prepareMarkerShape(Shape shape)
Prepares the layer for drawing the specified shape (QPolygonF version)
QPainterPath mPath
Painter path representing shape. If mPolygon is empty then the shape is stored in mPath.
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
static bool shapeIsFilled(QgsSimpleMarkerSymbolLayerBase::Shape shape)
Returns true if a symbol shape has a fill.
static QList< QgsSimpleMarkerSymbolLayerBase::Shape > availableShapes()
Returns a list of all available shape types.
QgsSimpleMarkerSymbolLayerBase::Shape shape() const
Returns the shape for the rendered marker symbol.
bool shapeToPolygon(Shape shape, QPolygonF &polygon) const
Creates a polygon representing the specified shape.
bool prepareMarkerPath(Shape symbol)
Prepares the layer for drawing the specified shape (QPainterPath version)
QgsSimpleMarkerSymbolLayerBase(QgsSimpleMarkerSymbolLayerBase::Shape shape=Circle, double size=DEFAULT_SIMPLEMARKER_SIZE, double angle=DEFAULT_SIMPLEMARKER_ANGLE, QgsSymbol::ScaleMethod scaleMethod=DEFAULT_SCALE_METHOD)
Constructor for QgsSimpleMarkerSymbolLayerBase.
QPolygonF mPolygon
Polygon of points in shape. If polygon is empty then shape is using mPath.
QRectF bounds(QPointF point, QgsSymbolRenderContext &context) override
Returns the approximate bounding box of the marker symbol layer, taking into account any data defined...
static QgsSimpleMarkerSymbolLayerBase::Shape decodeShape(const QString &name, bool *ok=nullptr)
Attempts to decode a string representation of a shape name to the corresponding shape.
static QString encodeShape(QgsSimpleMarkerSymbolLayerBase::Shape 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.
Shape
Marker symbol shapes.
@ ArrowHead
Right facing arrow head (unfilled, lines only)
@ Octagon
Octagon (since QGIS 3.18)
@ ThirdCircle
One third circle (top left third)
@ CrossFill
Solid filled cross.
@ RightHalfTriangle
Right half of triangle.
@ SquareWithCorners
A square with diagonal corners (since QGIS 3.18)
@ LeftHalfTriangle
Left half of triangle.
@ QuarterSquare
Quarter square (top left quarter)
@ ArrowHeadFilled
Right facing filled arrow head.
@ Cross2
Rotated cross (lines only), "x" shape.
@ Cross
Cross (lines only)
@ EquilateralTriangle
Equilateral triangle.
@ HalfSquare
Half square (left half)
@ QuarterCircle
Quarter circle (top left quarter)
@ SemiCircle
Semi circle (top half)
@ DiagonalHalfSquare
Diagonal half square (bottom left half)
@ AsteriskFill
A filled asterisk shape (since QGIS 3.18)
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
The fill color.
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
Set fill color.
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.
QgsSimpleMarkerSymbolLayer(QgsSimpleMarkerSymbolLayerBase::Shape shape=Circle, double size=DEFAULT_SIMPLEMARKER_SIZE, double angle=DEFAULT_SIMPLEMARKER_ANGLE, QgsSymbol::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.
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
The fill color.
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.
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
Gets fill color.
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.
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.
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
Gets fill color.
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
Set stroke color.
void setMapUnitScale(const QgsMapUnitScale &scale) override
double updateDefaultAspectRatio()
Calculates the default marker aspect ratio between width and height.
QColor strokeColor() const override
Gets stroke color.
void setFillColor(const QColor &color) override
Set fill color.
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.
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.
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.
QgsSvgMarkerSymbolLayer(const QString &path, double size=DEFAULT_SVGMARKER_SIZE, double angle=DEFAULT_SVGMARKER_ANGLE, QgsSymbol::ScaleMethod scaleMethod=DEFAULT_SCALE_METHOD)
Constructs SVG marker symbol layer with picture from given absolute path to a SVG file.
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 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 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 QgsSymbol::ScaleMethod decodeScaleMethod(const QString &str)
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 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 encodeScaleMethod(QgsSymbol::ScaleMethod scaleMethod)
static QString encodePenJoinStyle(Qt::PenJoinStyle style)
static QPointF decodePoint(const QString &string)
Decodes a QSizeF from a string.
@ PropertyStrokeStyle
Stroke style (eg solid, dashed)
@ 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 QColor color() const
The fill color.
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)
The fill color.
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.
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.
QgsSymbol::RenderHints renderHints() const
Returns the rendering hint flags for the symbol.
qreal opacity() const
Returns the opacity for the symbol.
Abstract base class for all rendered symbols.
@ ScaleArea
Calculate scale by the area.
@ ScaleDiameter
Calculate scale by the diameter.
SymbolType type() const
Returns the symbol's type.
@ DynamicRotation
Rotation of symbol may be changed during rendering and symbol should not be cached.
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