28 #include <QSvgRenderer> 31 #include <QDomDocument> 32 #include <QDomElement> 39 static void _fixQPictureDPI( QPainter *p )
45 p->scale( static_cast< double >(
qt_defaultDpiX() ) / p->device()->logicalDpiX(),
46 static_cast< double >(
qt_defaultDpiY() ) / p->device()->logicalDpiY() );
59 QList< Shape > shapes;
143 QTransform transform;
146 if ( !hasDataDefinedSize )
149 double half = scaledSize / 2.0;
150 transform.scale( half, half );
156 transform.rotate(
mAngle );
183 bool hasDataDefinedSize =
false;
184 double scaledSize =
calculateSize( context, hasDataDefinedSize );
186 bool hasDataDefinedRotation =
false;
192 bool createdNewPath =
false;
199 if ( exprVal.isValid() )
210 createdNewPath =
true;
219 QTransform transform;
222 transform.translate( point.x() + offset.x(), point.y() + offset.y() );
225 if ( hasDataDefinedSize || createdNewPath )
228 double half = s / 2.0;
229 transform.scale( half, half );
232 if ( !
qgsDoubleNear( angle, 0.0 ) && ( hasDataDefinedRotation || createdNewPath ) )
233 transform.rotate( angle );
241 polygon = transform.map(
mPolygon );
245 path = transform.map(
mPath );
247 draw( context, symbol, polygon, path );
252 bool hasDataDefinedSize =
false;
253 double scaledSize =
calculateSize( context, hasDataDefinedSize );
255 bool hasDataDefinedRotation =
false;
262 QTransform transform;
265 transform.translate( point.x() + offset.x(), point.y() + offset.y() );
268 transform.rotate( angle );
270 return transform.mapRect( QRectF( -scaledSize / 2.0,
280 QString cleaned = name.toLower().trimmed();
282 if ( cleaned == QLatin1String(
"square" ) || cleaned == QLatin1String(
"rectangle" ) )
284 else if ( cleaned == QLatin1String(
"diamond" ) )
286 else if ( cleaned == QLatin1String(
"pentagon" ) )
288 else if ( cleaned == QLatin1String(
"hexagon" ) )
290 else if ( cleaned == QLatin1String(
"triangle" ) )
292 else if ( cleaned == QLatin1String(
"equilateral_triangle" ) )
294 else if ( cleaned == QLatin1String(
"star" ) || cleaned == QLatin1String(
"regular_star" ) )
296 else if ( cleaned == QLatin1String(
"arrow" ) )
298 else if ( cleaned == QLatin1String(
"circle" ) )
300 else if ( cleaned == QLatin1String(
"cross" ) )
302 else if ( cleaned == QLatin1String(
"cross_fill" ) )
304 else if ( cleaned == QLatin1String(
"cross2" ) || cleaned == QLatin1String(
"x" ) )
306 else if ( cleaned == QLatin1String(
"line" ) )
308 else if ( cleaned == QLatin1String(
"arrowhead" ) )
310 else if ( cleaned == QLatin1String(
"filled_arrowhead" ) )
312 else if ( cleaned == QLatin1String(
"semi_circle" ) )
314 else if ( cleaned == QLatin1String(
"third_circle" ) )
316 else if ( cleaned == QLatin1String(
"quarter_circle" ) )
318 else if ( cleaned == QLatin1String(
"quarter_square" ) )
320 else if ( cleaned == QLatin1String(
"half_square" ) )
322 else if ( cleaned == QLatin1String(
"diagonal_half_square" ) )
324 else if ( cleaned == QLatin1String(
"right_half_triangle" ) )
326 else if ( cleaned == QLatin1String(
"left_half_triangle" ) )
339 return QStringLiteral(
"square" );
341 return QStringLiteral(
"quarter_square" );
343 return QStringLiteral(
"half_square" );
345 return QStringLiteral(
"diagonal_half_square" );
347 return QStringLiteral(
"diamond" );
349 return QStringLiteral(
"pentagon" );
351 return QStringLiteral(
"hexagon" );
353 return QStringLiteral(
"triangle" );
355 return QStringLiteral(
"equilateral_triangle" );
357 return QStringLiteral(
"left_half_triangle" );
359 return QStringLiteral(
"right_half_triangle" );
361 return QStringLiteral(
"star" );
363 return QStringLiteral(
"arrow" );
365 return QStringLiteral(
"filled_arrowhead" );
367 return QStringLiteral(
"cross_fill" );
369 return QStringLiteral(
"circle" );
371 return QStringLiteral(
"cross" );
373 return QStringLiteral(
"cross2" );
375 return QStringLiteral(
"line" );
377 return QStringLiteral(
"arrowhead" );
379 return QStringLiteral(
"semi_circle" );
381 return QStringLiteral(
"third_circle" );
383 return QStringLiteral(
"quarter_circle" );
400 polygon = QPolygonF( QRectF( QPointF( -1, -1 ), QPointF( 1, 1 ) ) );
404 polygon = QPolygonF( QRectF( QPointF( -1, -1 ), QPointF( 0, 0 ) ) );
408 polygon = QPolygonF( QRectF( QPointF( -1, -1 ), QPointF( 0, 1 ) ) );
412 polygon << QPointF( -1, -1 ) << QPointF( 1, 1 ) << QPointF( -1, 1 ) << QPointF( -1, -1 );
416 polygon << QPointF( -1, 0 ) << QPointF( 0, 1 )
417 << QPointF( 1, 0 ) << QPointF( 0, -1 ) << QPointF( -1, 0 );
427 polygon << QPointF( -0.9511, -0.3090 )
428 << QPointF( -0.5878, 0.8090 )
429 << QPointF( 0.5878, 0.8090 )
430 << QPointF( 0.9511, -0.3090 )
432 << QPointF( -0.9511, -0.3090 );
443 polygon << QPointF( -0.8660, -0.5 )
444 << QPointF( -0.8660, 0.5 )
446 << QPointF( 0.8660, 0.5 )
447 << QPointF( 0.8660, -0.5 )
449 << QPointF( -0.8660, -0.5 );
453 polygon << QPointF( -1, 1 ) << QPointF( 1, 1 ) << QPointF( 0, -1 ) << QPointF( -1, 1 );
461 polygon << QPointF( -0.8660, 0.5 )
462 << QPointF( 0.8660, 0.5 )
464 << QPointF( -0.8660, 0.5 );
468 polygon << QPointF( 0, 1 ) << QPointF( 1, 1 ) << QPointF( 0, -1 ) << QPointF( 0, 1 );
472 polygon << QPointF( -1, 1 ) << QPointF( 0, 1 ) << QPointF( 0, -1 ) << QPointF( -1, 1 );
477 double inner_r = std::cos(
DEG2RAD( 72.0 ) ) / std::cos(
DEG2RAD( 36.0 ) );
479 polygon << QPointF( inner_r * std::sin(
DEG2RAD( 324.0 ) ), - inner_r * std::cos(
DEG2RAD( 324.0 ) ) )
480 << QPointF( std::sin(
DEG2RAD( 288.0 ) ), - std::cos(
DEG2RAD( 288 ) ) )
481 << QPointF( inner_r * std::sin(
DEG2RAD( 252.0 ) ), - inner_r * std::cos(
DEG2RAD( 252.0 ) ) )
482 << QPointF( std::sin(
DEG2RAD( 216.0 ) ), - std::cos(
DEG2RAD( 216.0 ) ) )
483 << QPointF( 0, inner_r )
484 << QPointF( std::sin(
DEG2RAD( 144.0 ) ), - std::cos(
DEG2RAD( 144.0 ) ) )
485 << QPointF( inner_r * std::sin(
DEG2RAD( 108.0 ) ), - inner_r * std::cos(
DEG2RAD( 108.0 ) ) )
486 << QPointF( std::sin(
DEG2RAD( 72.0 ) ), - std::cos(
DEG2RAD( 72.0 ) ) )
487 << QPointF( inner_r * std::sin(
DEG2RAD( 36.0 ) ), - inner_r * std::cos(
DEG2RAD( 36.0 ) ) )
489 << QPointF( inner_r * std::sin(
DEG2RAD( 324.0 ) ), - inner_r * std::cos(
DEG2RAD( 324.0 ) ) );
494 polygon << QPointF( 0, -1 )
495 << QPointF( 0.5, -0.5 )
496 << QPointF( 0.25, -0.5 )
497 << QPointF( 0.25, 1 )
498 << QPointF( -0.25, 1 )
499 << QPointF( -0.25, -0.5 )
500 << QPointF( -0.5, -0.5 )
505 polygon << QPointF( 0, 0 ) << QPointF( -1, 1 ) << QPointF( -1, -1 ) << QPointF( 0, 0 );
509 polygon << QPointF( -1, -0.2 )
510 << QPointF( -1, -0.2 )
511 << QPointF( -1, 0.2 )
512 << QPointF( -0.2, 0.2 )
513 << QPointF( -0.2, 1 )
515 << QPointF( 0.2, 0.2 )
517 << QPointF( 1, -0.2 )
518 << QPointF( 0.2, -0.2 )
519 << QPointF( 0.2, -1 )
520 << QPointF( -0.2, -1 )
521 << QPointF( -0.2, -0.2 )
522 << QPointF( -1, -0.2 );
541 mPath = QPainterPath();
547 mPath.addEllipse( QRectF( -1, -1, 2, 2 ) );
551 mPath.arcTo( -1, -1, 2, 2, 0, 180 );
552 mPath.lineTo( 0, 0 );
556 mPath.arcTo( -1, -1, 2, 2, 90, 120 );
557 mPath.lineTo( 0, 0 );
561 mPath.arcTo( -1, -1, 2, 2, 90, 90 );
562 mPath.lineTo( 0, 0 );
566 mPath.moveTo( -1, 0 );
567 mPath.lineTo( 1, 0 );
568 mPath.moveTo( 0, -1 );
569 mPath.lineTo( 0, 1 );
573 mPath.moveTo( -1, -1 );
574 mPath.lineTo( 1, 1 );
575 mPath.moveTo( 1, -1 );
576 mPath.lineTo( -1, 1 );
580 mPath.moveTo( 0, -1 );
581 mPath.lineTo( 0, 1 );
585 mPath.moveTo( -1, -1 );
586 mPath.lineTo( 0, 0 );
587 mPath.lineTo( -1, 1 );
612 double scaledSize =
mSize;
616 if ( hasDataDefinedSize )
623 if ( hasDataDefinedSize && ok )
628 scaledSize = std::sqrt( scaledSize );
643 markerOffset( context, scaledSize, scaledSize, offsetX, offsetY );
644 offset = QPointF( offsetX, offsetY );
649 bool usingDataDefinedRotation =
false;
654 usingDataDefinedRotation = ok;
658 if ( hasDataDefinedRotation )
687 , mStrokeColor( strokeColor )
688 , mPenJoinStyle( penJoinStyle )
703 if ( props.contains( QStringLiteral(
"name" ) ) )
705 shape =
decodeShape( props[QStringLiteral(
"name" )] );
707 if ( props.contains( QStringLiteral(
"color" ) ) )
709 if ( props.contains( QStringLiteral(
"color_border" ) ) )
714 else if ( props.contains( QStringLiteral(
"outline_color" ) ) )
718 else if ( props.contains( QStringLiteral(
"line_color" ) ) )
722 if ( props.contains( QStringLiteral(
"joinstyle" ) ) )
726 if ( props.contains( QStringLiteral(
"size" ) ) )
727 size = props[QStringLiteral(
"size" )].toDouble();
728 if ( props.contains( QStringLiteral(
"angle" ) ) )
729 angle = props[QStringLiteral(
"angle" )].toDouble();
730 if ( props.contains( QStringLiteral(
"scale_method" ) ) )
734 if ( props.contains( QStringLiteral(
"offset" ) ) )
736 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
738 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
740 if ( props.contains( QStringLiteral(
"size_unit" ) ) )
742 if ( props.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
745 if ( props.contains( QStringLiteral(
"outline_style" ) ) )
749 else if ( props.contains( QStringLiteral(
"line_style" ) ) )
753 if ( props.contains( QStringLiteral(
"outline_width" ) ) )
755 m->
setStrokeWidth( props[QStringLiteral(
"outline_width" )].toDouble() );
757 else if ( props.contains( QStringLiteral(
"line_width" ) ) )
759 m->
setStrokeWidth( props[QStringLiteral(
"line_width" )].toDouble() );
761 if ( props.contains( QStringLiteral(
"outline_width_unit" ) ) )
765 if ( props.contains( QStringLiteral(
"line_width_unit" ) ) )
769 if ( props.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
774 if ( props.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
778 if ( props.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
791 return QStringLiteral(
"SimpleMarker" );
798 QColor brushColor =
mColor;
804 mBrush = QBrush( brushColor );
805 mPen = QPen( penColor );
814 selBrushColor.setAlphaF( context.
opacity() );
815 selPenColor.setAlphaF( context.
opacity() );
837 mSelPen.setColor( selBrushColor );
861 double pw =
static_cast< int >( std::round( ( (
qgsDoubleNear(
mPen.widthF(), 0.0 ) ? 1 :
mPen.widthF() * 4 ) + 1 ) ) ) / 2 * 2;
862 int imageSize = (
static_cast< int >( scaledSize ) + pw ) / 2 * 2 + 1;
863 double center = imageSize / 2.0;
870 mCache = QImage( QSize( imageSize, imageSize ), QImage::Format_ARGB32_Premultiplied );
877 p.setRenderHint( QPainter::Antialiasing );
878 p.setBrush( needsBrush ?
mBrush : Qt::NoBrush );
880 p.translate( QPointF( center, center ) );
888 mSelCache = QImage( QSize( imageSize, imageSize ), QImage::Format_ARGB32_Premultiplied );
892 p.setRenderHint( QPainter::Antialiasing );
893 p.setBrush( needsBrush ?
mSelBrush : Qt::NoBrush );
895 p.translate( QPointF( center, center ) );
906 p.setRenderHint( QPainter::Antialiasing );
907 p.fillRect( 0, 0, imageSize, imageSize, selColor );
908 p.setBrush( needsBrush ?
mBrush : Qt::NoBrush );
910 p.translate( QPointF( center, center ) );
984 p->setBrush( Qt::NoBrush );
988 if ( !polygon.isEmpty() )
989 p->drawPolygon( polygon );
1008 double s = img.width();
1010 bool hasDataDefinedSize =
false;
1011 double scaledSize =
calculateSize( context, hasDataDefinedSize );
1013 bool hasDataDefinedRotation =
false;
1018 p->drawImage( QRectF( point.x() - s / 2.0 + offset.x(),
1019 point.y() - s / 2.0 + offset.y(),
1034 map[QStringLiteral(
"size" )] = QString::number(
mSize );
1037 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
1043 map[QStringLiteral(
"outline_width" )] = QString::number(
mStrokeWidth );
1074 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
1075 element.appendChild( graphicElem );
1084 double angle = props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toDouble( &ok );
1087 angleFunc = QStringLiteral(
"%1 + %2" ).arg( props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ) ).arg(
mAngle );
1091 angleFunc = QString::number( angle +
mAngle );
1102 Q_UNUSED( mmScaleFactor );
1103 Q_UNUSED( mapUnitScaleFactor );
1105 QString ogrType =
"3";
1106 if ( mName ==
"square" )
1110 else if ( mName ==
"triangle" )
1114 else if ( mName ==
"star" )
1118 else if ( mName ==
"circle" )
1122 else if ( mName ==
"cross" )
1126 else if ( mName ==
"x" || mName ==
"cross2" )
1130 else if ( mName ==
"line" )
1136 ogrString.append(
"SYMBOL(" );
1137 ogrString.append(
"id:" );
1138 ogrString.append(
'\"' );
1139 ogrString.append(
"ogr-sym-" );
1140 ogrString.append( ogrType );
1141 ogrString.append(
'\"' );
1142 ogrString.append(
",c:" );
1143 ogrString.append(
mColor.name() );
1144 ogrString.append(
",o:" );
1146 ogrString.append( QString(
",s:%1mm" ).arg(
mSize ) );
1147 ogrString.append(
')' );
1152 ogrString.append(
"PEN(" );
1153 ogrString.append(
"c:" );
1154 ogrString.append(
mColor.name() );
1155 ogrString.append(
",w:" );
1156 ogrString.append( QString::number(
mSize ) );
1157 ogrString.append(
"mm" );
1158 ogrString.append(
")" );
1166 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
1167 if ( graphicElem.isNull() )
1170 QString name = QStringLiteral(
"square" );
1183 double d = angleFunc.toDouble( &ok );
1193 QString uom = element.attribute( QStringLiteral(
"uom" ) );
1211 Q_UNUSED( context );
1219 p->drawPath(
mPath );
1225 Q_UNUSED( mmMapUnitScaleFactor );
1234 if ( hasDataDefinedSize )
1243 size = std::sqrt( size );
1256 double halfSize = size / 2.0;
1273 QColor pc =
mPen.color();
1274 QColor bc =
mBrush.color();
1294 QPointF off( offsetX, offsetY );
1323 t.translate( shift.x() + off.x(), shift.y() - off.y() );
1331 t.scale( halfSize, -halfSize );
1333 polygon = t.map( polygon );
1336 p.reserve( polygon.size() );
1337 for (
int i = 0; i < polygon.size(); i++ )
1342 if (
mBrush.style() != Qt::NoBrush )
1344 if (
mPen.style() != Qt::NoPen )
1345 e.
writePolyline( p, layerName, QStringLiteral(
"CONTINUOUS" ), pc, strokeWidth );
1347 else if ( shape ==
Circle )
1349 shift += QPointF( off.x(), -off.y() );
1350 if (
mBrush.style() != Qt::NoBrush )
1352 if (
mPen.style() != Qt::NoPen )
1353 e.
writeCircle( layerName, pc,
QgsPoint( shift ), halfSize, QStringLiteral(
"CONTINUOUS" ), strokeWidth );
1355 else if ( shape ==
Line )
1357 QPointF pt1 = t.map( QPointF( 0, -halfSize ) );
1358 QPointF pt2 = t.map( QPointF( 0, halfSize ) );
1360 if (
mPen.style() != Qt::NoPen )
1363 else if ( shape ==
Cross )
1365 if (
mPen.style() != Qt::NoPen )
1367 QPointF pt1 = t.map( QPointF( -halfSize, 0 ) );
1368 QPointF pt2 = t.map( QPointF( halfSize, 0 ) );
1369 QPointF pt3 = t.map( QPointF( 0, -halfSize ) );
1370 QPointF pt4 = t.map( QPointF( 0, halfSize ) );
1376 else if ( shape ==
Cross2 )
1378 if (
mPen.style() != Qt::NoPen )
1380 QPointF pt1 = t.map( QPointF( -halfSize, -halfSize ) );
1381 QPointF pt2 = t.map( QPointF( halfSize, halfSize ) );
1382 QPointF pt3 = t.map( QPointF( halfSize, -halfSize ) );
1383 QPointF pt4 = t.map( QPointF( -halfSize, halfSize ) );
1391 if (
mPen.style() != Qt::NoPen )
1393 QPointF pt1 = t.map( QPointF( -halfSize, halfSize ) );
1394 QPointF pt2 = t.map( QPointF( 0, 0 ) );
1395 QPointF pt3 = t.map( QPointF( -halfSize, -halfSize ) );
1446 double penWidth = 0.0;
1461 if ( ok && strokeStyle == QLatin1String(
"no" ) )
1470 symbolBounds.adjust( -penWidth / 2.0, -penWidth / 2.0,
1471 penWidth / 2.0, penWidth / 2.0 );
1473 return symbolBounds;
1520 if ( props.contains( QStringLiteral(
"name" ) ) )
1521 name = props[QStringLiteral(
"name" )];
1522 if ( props.contains( QStringLiteral(
"size" ) ) )
1523 size = props[QStringLiteral(
"size" )].toDouble();
1524 if ( props.contains( QStringLiteral(
"angle" ) ) )
1525 angle = props[QStringLiteral(
"angle" )].toDouble();
1526 if ( props.contains( QStringLiteral(
"scale_method" ) ) )
1530 if ( props.contains( QStringLiteral(
"offset" ) ) )
1532 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
1534 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
1536 if ( props.contains( QStringLiteral(
"size_unit" ) ) )
1538 if ( props.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
1540 if ( props.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
1544 if ( props.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
1558 return QStringLiteral(
"FilledMarker" );
1583 map[QStringLiteral(
"size" )] = QString::number(
mSize );
1586 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
1619 mFill.reset( static_cast<QgsFillSymbol *>( symbol ) );
1642 attr.unite( mFill->usedAttributes( context ) );
1650 if ( mFill && mFill->hasDataDefinedProperties() )
1659 mFill->setColor( c );
1664 return mFill ? mFill->color() :
mColor;
1680 p->setBrush( Qt::red );
1684 p->setBrush( Qt::NoBrush );
1686 p->setPen( Qt::black );
1688 if ( !polygon.isEmpty() )
1694 QPolygonF poly = path.toFillPolygon();
1714 mColor = QColor( 35, 35, 35 );
1715 mStrokeColor = QColor( 35, 35, 35 );
1716 updateDefaultAspectRatio();
1727 if ( props.contains( QStringLiteral(
"name" ) ) )
1728 name = props[QStringLiteral(
"name" )];
1729 if ( props.contains( QStringLiteral(
"size" ) ) )
1730 size = props[QStringLiteral(
"size" )].toDouble();
1731 if ( props.contains( QStringLiteral(
"angle" ) ) )
1732 angle = props[QStringLiteral(
"angle" )].toDouble();
1733 if ( props.contains( QStringLiteral(
"scale_method" ) ) )
1739 if ( !props.contains( QStringLiteral(
"fill" ) ) && !props.contains( QStringLiteral(
"color" ) ) && !props.contains( QStringLiteral(
"outline" ) ) &&
1740 !props.contains( QStringLiteral(
"outline_color" ) ) && !props.contains( QStringLiteral(
"outline-width" ) ) && !props.contains( QStringLiteral(
"outline_width" ) ) )
1743 double fillOpacity = 1.0;
1744 double strokeOpacity = 1.0;
1746 bool hasFillParam =
false, hasFillOpacityParam =
false, hasStrokeParam =
false, hasStrokeWidthParam =
false, hasStrokeOpacityParam =
false;
1747 bool hasDefaultFillColor =
false, hasDefaultFillOpacity =
false, hasDefaultStrokeColor =
false, hasDefaultStrokeWidth =
false, hasDefaultStrokeOpacity =
false;
1749 hasFillOpacityParam, hasDefaultFillOpacity, fillOpacity,
1750 hasStrokeParam, hasDefaultStrokeColor, strokeColor,
1751 hasStrokeWidthParam, hasDefaultStrokeWidth, strokeWidth,
1752 hasStrokeOpacityParam, hasDefaultStrokeOpacity, strokeOpacity );
1753 if ( hasDefaultFillColor )
1757 if ( hasDefaultFillOpacity )
1760 c.setAlphaF( fillOpacity );
1763 if ( hasDefaultStrokeColor )
1767 if ( hasDefaultStrokeWidth )
1771 if ( hasDefaultStrokeOpacity )
1774 c.setAlphaF( strokeOpacity );
1779 if ( props.contains( QStringLiteral(
"size_unit" ) ) )
1781 if ( props.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
1783 if ( props.contains( QStringLiteral(
"fixedAspectRatio" ) ) )
1785 if ( props.contains( QStringLiteral(
"offset" ) ) )
1787 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
1789 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
1791 if ( props.contains( QStringLiteral(
"fill" ) ) )
1796 else if ( props.contains( QStringLiteral(
"color" ) ) )
1800 if ( props.contains( QStringLiteral(
"outline" ) ) )
1805 else if ( props.contains( QStringLiteral(
"outline_color" ) ) )
1809 else if ( props.contains( QStringLiteral(
"line_color" ) ) )
1814 if ( props.contains( QStringLiteral(
"outline-width" ) ) )
1817 m->
setStrokeWidth( props[QStringLiteral(
"outline-width" )].toDouble() );
1819 else if ( props.contains( QStringLiteral(
"outline_width" ) ) )
1821 m->
setStrokeWidth( props[QStringLiteral(
"outline_width" )].toDouble() );
1823 else if ( props.contains( QStringLiteral(
"line_width" ) ) )
1825 m->
setStrokeWidth( props[QStringLiteral(
"line_width" )].toDouble() );
1828 if ( props.contains( QStringLiteral(
"outline_width_unit" ) ) )
1832 else if ( props.contains( QStringLiteral(
"line_width_unit" ) ) )
1836 if ( props.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
1839 if ( props.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
1843 if ( props.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
1857 QgsStringMap::iterator it = properties.find( QStringLiteral(
"name" ) );
1858 if ( it != properties.end() )
1870 QColor defaultFillColor, defaultStrokeColor;
1871 double strokeWidth, fillOpacity, strokeOpacity;
1872 bool hasFillParam =
false, hasFillOpacityParam =
false, hasStrokeParam =
false, hasStrokeWidthParam =
false, hasStrokeOpacityParam =
false;
1873 bool hasDefaultFillColor =
false, hasDefaultFillOpacity =
false, hasDefaultStrokeColor =
false, hasDefaultStrokeWidth =
false, hasDefaultStrokeOpacity =
false;
1875 hasFillOpacityParam, hasDefaultFillOpacity, fillOpacity,
1876 hasStrokeParam, hasDefaultStrokeColor, defaultStrokeColor,
1877 hasStrokeWidthParam, hasDefaultStrokeWidth, strokeWidth,
1878 hasStrokeOpacityParam, hasDefaultStrokeOpacity, strokeOpacity );
1880 double newFillOpacity = hasFillOpacityParam ?
fillColor().alphaF() : 1.0;
1881 double newStrokeOpacity = hasStrokeOpacityParam ?
strokeColor().alphaF() : 1.0;
1883 if ( hasDefaultFillColor )
1885 defaultFillColor.setAlphaF( newFillOpacity );
1888 if ( hasDefaultFillOpacity )
1891 c.setAlphaF( fillOpacity );
1894 if ( hasDefaultStrokeColor )
1896 defaultStrokeColor.setAlphaF( newStrokeOpacity );
1899 if ( hasDefaultStrokeWidth )
1901 setStrokeWidth( strokeWidth );
1903 if ( hasDefaultStrokeOpacity )
1906 c.setAlphaF( strokeOpacity );
1910 updateDefaultAspectRatio();
1915 if ( mDefaultAspectRatio == 0.0 )
1920 double widthScaleFactor = 3.465;
1923 mDefaultAspectRatio = svgViewbox.isValid() ? svgViewbox.height() / svgViewbox.width() : 0.0;
1925 return mDefaultAspectRatio;
1930 bool aPreservedAspectRatio = preservedAspectRatio();
1931 if ( aPreservedAspectRatio && !par )
1933 mFixedAspectRatio = mDefaultAspectRatio;
1935 else if ( !aPreservedAspectRatio && par )
1937 mFixedAspectRatio = 0.0;
1939 return preservedAspectRatio();
1945 return QStringLiteral(
"SvgMarker" );
1951 Q_UNUSED( context );
1956 Q_UNUSED( context );
1965 bool hasDataDefinedSize =
false;
1966 double scaledSize =
calculateSize( context, hasDataDefinedSize );
1970 if ( static_cast< int >( size ) < 1 || 10000.0 < size )
1977 bool hasDataDefinedAspectRatio =
false;
1978 double aspectRatio = calculateAspectRatio( context, scaledSize, hasDataDefinedAspectRatio );
1980 QPointF outputOffset;
1984 p->translate( point + outputOffset );
1990 QString path =
mPath;
1998 double strokeWidth = mStrokeWidth;
2020 bool fitsInCache =
true;
2021 bool usePict =
true;
2022 double hwRatio = 1.0;
2027 if ( fitsInCache && img.width() > 1 )
2033 QImage transparentImage = img.copy();
2035 p->drawImage( -transparentImage.width() / 2.0, -transparentImage.height() / 2.0, transparentImage );
2036 hwRatio =
static_cast< double >( transparentImage.height() ) / static_cast< double >( transparentImage.width() );
2040 p->drawImage( -img.width() / 2.0, -img.height() / 2.0, img );
2041 hwRatio =
static_cast< double >( img.height() ) / static_cast< double >( img.width() );
2046 if ( usePict || !fitsInCache )
2048 p->setOpacity( context.
opacity() );
2051 if ( pct.width() > 1 )
2054 _fixQPictureDPI( p );
2055 p->drawPicture( 0, 0, pct );
2057 hwRatio =
static_cast< double >( pct.height() ) / static_cast< double >( pct.width() );
2065 if ( penWidth > size / 20 )
2068 penWidth = size / 20;
2070 double penOffset = penWidth / 2;
2071 pen.setWidth( penWidth );
2073 p->setBrush( Qt::NoBrush );
2074 double wSize = size + penOffset;
2075 double hSize = size * hwRatio + penOffset;
2076 p->drawRect( QRectF( -wSize / 2.0, -hSize / 2.0, wSize, hSize ) );
2084 p->setRenderHint( QPainter::Antialiasing );
2089 double QgsSvgMarkerSymbolLayer::calculateSize(
QgsSymbolRenderContext &context,
bool &hasDataDefinedSize )
const 2091 double scaledSize =
mSize;
2095 if ( hasDataDefinedSize )
2103 if ( hasDataDefinedSize )
2110 if ( hasDataDefinedSize && ok )
2115 scaledSize = std::sqrt( scaledSize );
2128 if ( !hasDataDefinedAspectRatio )
2129 return mFixedAspectRatio;
2134 double scaledAspectRatio = mDefaultAspectRatio;
2135 if ( mFixedAspectRatio > 0.0 )
2136 scaledAspectRatio = mFixedAspectRatio;
2138 double defaultHeight =
mSize * scaledAspectRatio;
2139 scaledAspectRatio = defaultHeight / scaledSize;
2142 double scaledHeight = scaledSize * scaledAspectRatio;
2149 if ( hasDataDefinedAspectRatio && ok )
2154 scaledHeight = sqrt( scaledHeight );
2161 scaledAspectRatio = scaledHeight / scaledSize;
2163 return scaledAspectRatio;
2171 markerOffset( context, scaledSize, scaledSize, offsetX, offsetY );
2172 offset = QPointF( offsetX, offsetY );
2182 if ( hasDataDefinedRotation )
2208 map[QStringLiteral(
"name" )] =
mPath;
2209 map[QStringLiteral(
"size" )] = QString::number(
mSize );
2212 map[QStringLiteral(
"fixedAspectRatio" )] = QString::number( mFixedAspectRatio );
2213 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
2220 map[QStringLiteral(
"outline_width" )] = QString::number( mStrokeWidth );
2252 mStrokeWidthUnit = unit;
2258 if ( unit != mStrokeWidthUnit )
2268 mStrokeWidthMapUnitScale = scale;
2275 return mStrokeWidthMapUnitScale;
2283 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
2284 element.appendChild( graphicElem );
2294 double angle = props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toDouble( &ok );
2297 angleFunc = QStringLiteral(
"%1 + %2" ).arg( props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ) ).arg(
mAngle );
2301 angleFunc = QString::number( angle +
mAngle );
2315 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
2316 if ( graphicElem.isNull() )
2319 QString path, mimeType;
2326 QString uom = element.attribute( QStringLiteral(
"uom" ) );
2329 if ( mimeType != QLatin1String(
"image/svg+xml" ) )
2337 double d = angleFunc.toDouble( &ok );
2363 if ( hasDataDefinedSize )
2369 if ( hasDataDefinedSize && ok )
2374 size = std::sqrt( size );
2383 size *= mmMapUnitScaleFactor;
2396 double offsetX = offset.x();
2397 double offsetY = offset.y();
2399 QPointF outputOffset( offsetX, offsetY );
2413 QString path =
mPath;
2421 double strokeWidth = mStrokeWidth;
2446 QSvgRenderer r( svgContent );
2453 QSizeF outSize( r.defaultSize() );
2454 outSize.scale( size, size, Qt::KeepAspectRatio );
2460 p.translate( r.defaultSize().width() / 2.0, r.defaultSize().height() / 2.0 );
2462 p.translate( -r.defaultSize().width() / 2.0, -r.defaultSize().height() / 2.0 );
2464 pd.
setShift( shift + QPointF( outputOffset.x(), -outputOffset.y() ) );
2465 pd.
setOutputSize( QRectF( -outSize.width() / 2.0, -outSize.height() / 2.0, outSize.width(), outSize.height() ) );
2474 bool hasDataDefinedSize =
false;
2475 double scaledSize =
calculateSize( context, hasDataDefinedSize );
2479 if ( static_cast< int >( scaledSize ) < 1 || 10000.0 < scaledSize )
2484 QPointF outputOffset;
2488 QString path =
mPath;
2496 double strokeWidth = mStrokeWidth;
2522 double scaledHeight = svgViewbox.isValid() ? scaledSize * svgViewbox.height() / svgViewbox.width() : scaledSize;
2527 transform.translate( point.x() + outputOffset.x(), point.y() + outputOffset.y() );
2530 transform.rotate( angle );
2533 strokeWidth += 1.0 / 2.0;
2535 QRectF symbolBounds = transform.mapRect( QRectF( -scaledSize / 2.0,
2536 -scaledHeight / 2.0,
2541 symbolBounds.adjust( -strokeWidth / 2.0, -strokeWidth / 2.0,
2542 strokeWidth / 2.0, strokeWidth / 2.0 );
2544 return symbolBounds;
2552 mFontFamily = fontFamily;
2557 mOrigSize = pointSize;
2569 delete mFontMetrics;
2580 if ( props.contains( QStringLiteral(
"font" ) ) )
2581 fontFamily = props[QStringLiteral(
"font" )];
2582 if ( props.contains( QStringLiteral(
"chr" ) ) && props[QStringLiteral(
"chr" )].length() > 0 )
2583 chr = props[QStringLiteral(
"chr" )].at( 0 );
2584 if ( props.contains( QStringLiteral(
"size" ) ) )
2585 pointSize = props[QStringLiteral(
"size" )].toDouble();
2586 if ( props.contains( QStringLiteral(
"color" ) ) )
2588 if ( props.contains( QStringLiteral(
"angle" ) ) )
2589 angle = props[QStringLiteral(
"angle" )].toDouble();
2593 if ( props.contains( QStringLiteral(
"outline_color" ) ) )
2595 if ( props.contains( QStringLiteral(
"outline_width" ) ) )
2596 m->
setStrokeWidth( props[QStringLiteral(
"outline_width" )].toDouble() );
2597 if ( props.contains( QStringLiteral(
"offset" ) ) )
2599 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
2601 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
2603 if ( props.contains( QStringLiteral(
"size_unit" ) ) )
2605 if ( props.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
2607 if ( props.contains( QStringLiteral(
"outline_width_unit" ) ) )
2609 if ( props.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
2611 if ( props.contains( QStringLiteral(
"joinstyle" ) ) )
2613 if ( props.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
2615 if ( props.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
2625 return QStringLiteral(
"FontMarker" );
2630 QColor brushColor =
mColor;
2631 QColor penColor = mStrokeColor;
2633 brushColor.setAlphaF(
mColor.alphaF() * context.
opacity() );
2634 penColor.setAlphaF( mStrokeColor.alphaF() * context.
opacity() );
2636 mBrush = QBrush( brushColor );
2637 mPen = QPen( penColor );
2638 mPen.setJoinStyle( mPenJoinStyle );
2641 mFont = QFont( mFontFamily );
2646 mFont.setPixelSize( std::max( 2, static_cast< int >( std::round( sizePixels ) ) ) );
2647 delete mFontMetrics;
2648 mFontMetrics =
new QFontMetrics( mFont );
2649 mChrWidth = mFontMetrics->width( mChr );
2650 mChrOffset = QPointF( mChrWidth / 2.0, -mFontMetrics->ascent() / 2.0 );
2655 if ( mUseCachedPath )
2657 QPointF chrOffset = mChrOffset;
2659 QString charToRender = characterToRender( context, chrOffset, chrWidth );
2660 mCachedPath = QPainterPath();
2661 mCachedPath.addText( -chrOffset.x(), -chrOffset.y(), mFont, charToRender );
2667 Q_UNUSED( context );
2670 QString QgsFontMarkerSymbolLayer::characterToRender(
QgsSymbolRenderContext &context, QPointF &charOffset,
double &charWidth )
2672 charOffset = mChrOffset;
2673 QString charToRender = mChr;
2678 if ( charToRender != mChr )
2680 charWidth = mFontMetrics->width( charToRender );
2681 charOffset = QPointF( charWidth / 2.0, -mFontMetrics->ascent() / 2.0 );
2684 return charToRender;
2689 bool &hasDataDefinedRotation,
2691 double &angle )
const 2696 markerOffset( context, scaledSize, scaledSize, offsetX, offsetY );
2697 offset = QPointF( offsetX, offsetY );
2702 bool usingDataDefinedRotation =
false;
2707 usingDataDefinedRotation = ok;
2711 if ( hasDataDefinedRotation )
2735 double scaledSize =
mSize;
2739 if ( hasDataDefinedSize )
2745 if ( hasDataDefinedSize && ok )
2750 scaledSize = std::sqrt( scaledSize );
2762 if ( !p || !mNonZeroFontSize )
2765 QTransform transform;
2768 QColor brushColor =
mColor;
2775 brushColor.setAlphaF( brushColor.alphaF() * context.
opacity() );
2776 mBrush.setColor( brushColor );
2778 QColor penColor = mStrokeColor;
2784 penColor.setAlphaF( penColor.alphaF() * context.
opacity() );
2808 p->setBrush( mBrush );
2811 mPen.setColor( penColor );
2812 mPen.setWidthF( penWidth );
2817 p->setPen( Qt::NoPen );
2820 QPointF chrOffset = mChrOffset;
2822 QString charToRender = characterToRender( context, chrOffset, chrWidth );
2826 bool hasDataDefinedRotation =
false;
2831 p->translate( point.x() + offset.x(), point.y() + offset.y() );
2834 transform.rotate( angle );
2838 double s = sizeToRender / mOrigSize;
2839 transform.scale( s, s );
2842 if ( mUseCachedPath )
2844 p->drawPath( transform.map( mCachedPath ) );
2849 path.addText( -chrOffset.x(), -chrOffset.y(), mFont, charToRender );
2850 p->drawPath( transform.map( path ) );
2859 props[QStringLiteral(
"font" )] = mFontFamily;
2860 props[QStringLiteral(
"chr" )] = mChr;
2861 props[QStringLiteral(
"size" )] = QString::number(
mSize );
2866 props[QStringLiteral(
"outline_width" )] = QString::number( mStrokeWidth );
2870 props[QStringLiteral(
"angle" )] = QString::number(
mAngle );
2902 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
2903 element.appendChild( graphicElem );
2905 QString fontPath = QStringLiteral(
"ttf://%1" ).arg( mFontFamily );
2906 int markIndex = mChr.unicode();
2913 double angle = props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toDouble( &ok );
2916 angleFunc = QStringLiteral(
"%1 + %2" ).arg( props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ) ).arg(
mAngle );
2920 angleFunc = QString::number( angle +
mAngle );
2931 QPointF chrOffset = mChrOffset;
2932 double chrWidth = mChrWidth;
2934 ( void )characterToRender( context, chrOffset, chrWidth );
2936 if ( !mFontMetrics )
2937 mFontMetrics =
new QFontMetrics( mFont );
2942 chrWidth *= scaledSize / mOrigSize;
2945 bool hasDataDefinedRotation =
false;
2954 transform.translate( point.x() + offset.x(), point.y() + offset.y() );
2957 transform.rotate( angle );
2959 QRectF symbolBounds = transform.mapRect( QRectF( -chrWidth / 2.0,
2963 return symbolBounds;
2970 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
2971 if ( graphicElem.isNull() )
2974 QString name, format;
2982 if ( !name.startsWith( QLatin1String(
"ttf://" ) ) || format != QLatin1String(
"ttf" ) )
2985 QString fontFamily = name.mid( 6 );
2992 double d = angleFunc.toDouble( &ok );
3000 QString uom = element.attribute( QStringLiteral(
"uom" ) );
bool prepareCache(QgsSymbolRenderContext &context)
Prepares cache image.
void setOffset(QPointF offset)
Sets the marker's offset, which is the horizontal and vertical displacement which the rendered marker...
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)
QPicture svgAsPicture(const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth, double widthScaleFactor, bool forceVectorOutput=false, double fixedAspectRatio=0)
Gets SVG as QPicture&.
#define DEFAULT_SIMPLEMARKER_SIZE
QgsMapUnitScale mapUnitScale() const override
double calculateSize(QgsSymbolRenderContext &context, bool &hasDataDefinedSize) const
Calculates the desired size of the marker, considering data defined size overrides.
static QgsSvgCache * svgCache()
Returns the application's SVG cache, used for caching SVG images and handling parameter replacement w...
QRectF bounds(QPointF point, QgsSymbolRenderContext &context) override
Returns the approximate bounding box of the marker symbol layer, taking into account any data defined...
bool writeDxf(QgsDxfExport &e, double mmMapUnitScaleFactor, const QString &layerName, QgsSymbolRenderContext &context, QPointF shift=QPointF(0.0, 0.0)) const override
write as DXF
QRectF bounds(QPointF point, QgsSymbolRenderContext &context) override
Returns the approximate bounding box of the marker symbol layer, taking into account any data defined...
QString ogrFeatureStyle(double mmScaleFactor, double mapUnitScaleFactor) const override
void setOffsetUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the symbol's offset.
static QgsSymbolLayer * createFromSld(QDomElement &element)
Creates a new QgsSimpleMarkerSymbolLayer from an SLD XML element.
static QgsSymbol::ScaleMethod decodeScaleMethod(const QString &str)
void setStrokeWidthMapUnitScale(const QgsMapUnitScale &scale)
Sets the stroke width map unit scale.
void writeLine(const QgsPoint &pt1, const QgsPoint &pt2, const QString &layer, const QString &lineStyleName, const QColor &color, double width=-1)
Write line (as a polyline)
void setColor(const QColor &c) override
The fill color.
QColor mStrokeColor
Stroke color.
virtual QColor strokeColor() const
Gets stroke color.
QgsUnitTypes::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
Qt::PenStyle mStrokeStyle
Stroke style.
QgsSymbol::RenderHints renderHints() const
Returns the rendering hint flags for the symbol.
Calculate scale by the diameter.
double symbologyScale() const
Returns the reference scale for output.
Abstract base class for all rendered symbols.
A paint device for drawing into dxf files.
#define DEFAULT_SIMPLEMARKER_NAME
Use antialiasing while drawing.
void setStrokeWidthUnit(QgsUnitTypes::RenderUnit u)
Sets the unit for the width of the marker's stroke.
void setMapUnitScale(const QgsMapUnitScale &scale) override
void setStrokeStyle(Qt::PenStyle strokeStyle)
Sets the marker's stroke style (e.g., solid, dashed, etc)
QColor selectionColor() const
Returns the color to use when rendering selected features.
void setOutputUnit(QgsUnitTypes::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
Simple marker symbol layer, consisting of a rendered shape with solid fill color and an stroke...
void writePolyline(const QgsPointSequence &line, const QString &layer, const QString &lineStyleName, const QColor &color, double width=-1)
Draw dxf primitives (LWPOLYLINE)
Abstract base class for simple marker symbol layers.
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...
QImage svgAsImage(const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth, double widthScaleFactor, bool &fitsInCache, double fixedAspectRatio=0)
Gets SVG as QImage.
QgsFontMarkerSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
Right facing filled arrow head.
double convertToPainterUnits(double size, QgsUnitTypes::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale()) const
Converts a size from the specified units to painter units (pixels).
Right facing arrow head (unfilled, lines only)
QPointF offset() const
Returns the marker's offset, which is the horizontal and vertical displacement which the rendered mar...
static QgsFillSymbol * createSimple(const QgsStringMap &properties)
Create a fill symbol with one symbol layer: SimpleFill with specified properties. ...
void startRender(QgsSymbolRenderContext &context) override
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
void renderPoint(QPointF point, QgsSymbolRenderContext &context) override
Renders a marker at the specified point.
double mLineAngle
Line rotation angle (see setLineAngle() for details)
void setDrawingSize(QSizeF size)
double size() const
Returns the symbol size.
QgsUnitTypes::RenderUnit mSizeUnit
Marker size unit.
QgsMapUnitScale mapUnitScale() const override
QgsMapUnitScale mStrokeWidthMapUnitScale
Stroke width map unit scale.
static bool displacementFromSldElement(QDomElement &element, QPointF &offset)
static QPointF decodePoint(const QString &string)
Decodes a QSizeF from a string.
void setStrokeColor(const QColor &color) override
Sets the marker's stroke color.
void writeSldMarker(QDomDocument &doc, QDomElement &element, const QgsStringMap &props) const override
Writes the symbol layer definition as a SLD XML element.
static void externalMarkerToSld(QDomDocument &doc, QDomElement &element, const QString &path, const QString &format, int *markIndex=nullptr, const QColor &color=QColor(), double size=-1)
void setStrokeColor(const QColor &c) override
Set stroke color.
void setStrokeWidth(double w)
Sets the width of the marker's stroke.
static const int MAXIMUM_CACHE_WIDTH
Maximum width/height of cache image.
static QString encodeMapUnitScale(const QgsMapUnitScale &mapUnitScale)
#define DEFAULT_FONTMARKER_COLOR
static void createDisplacementElement(QDomDocument &doc, QDomElement &element, QPointF offset)
QBrush mSelBrush
QBrush to use as fill of selected symbols.
static QgsSimpleMarkerSymbolLayerBase::Shape decodeShape(const QString &name, bool *ok=nullptr)
Attempts to decode a string representation of a shape name to the corresponding shape.
void setOffsetMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the symbol's offset.
void restoreOldDataDefinedProperties(const QgsStringMap &stringMap)
Restores older data defined properties from string map.
void setStrokeWidth(double width)
Set's the marker's stroke width.
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
static double sizeInPixelsFromSldUom(const QString &uom, double size)
Returns the size scaled in pixels according to the uom attribute.
#define DEFAULT_FONTMARKER_BORDERCOLOR
QgsUnitTypes::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
QPointF mOffset
Marker offset.
double scaleFactor() const
Returns the scaling factor for the render to convert painter units to physical sizes.
QColor strokeColor() const override
Returns the marker's stroke color.
void startRender(QgsSymbolRenderContext &context) override
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
static bool rotationFromSldElement(QDomElement &element, QString &rotationFunc)
QgsUnitTypes::RenderUnit mStrokeWidthUnit
Stroke width units.
#define DEFAULT_SIMPLEMARKER_JOINSTYLE
void clipValueToMapUnitScale(double &value, const QgsMapUnitScale &scale, double pixelToMMFactor) const
Clips value to scale minimum/maximum.
static QString encodeShape(QgsSimpleMarkerSymbolLayerBase::Shape shape)
Encodes a shape to its string representation.
QgsMapUnitScale mapUnitScale() const override
QMap< QString, QString > QgsStringMap
double mapRotation() const
Returns current map rotation in degrees.
void calculateOffsetAndRotation(QgsSymbolRenderContext &context, double scaledSize, bool &hasDataDefinedRotation, QPointF &offset, double &angle) const
Calculates the marker offset and rotation.
Rotation of symbol may be changed during rendering and symbol should not be cached.
QgsFontMarkerSymbolLayer(const QString &fontFamily=DEFAULT_FONTMARKER_FONT, QChar chr=DEFAULT_FONTMARKER_CHR, double pointSize=DEFAULT_FONTMARKER_SIZE, const QColor &color=DEFAULT_FONTMARKER_COLOR, double angle=DEFAULT_FONTMARKER_ANGLE)
static QString encodePoint(QPointF point)
Encodes a QPointF to a string.
Name, eg shape name for simple markers.
static Qt::PenJoinStyle decodePenJoinStyle(const QString &str)
void renderPoint(QPointF point, QgsSymbolRenderContext &context) override
Renders a marker at the specified point.
static QList< QgsSimpleMarkerSymbolLayerBase::Shape > availableShapes()
Returns a list of all available shape types.
bool isActive(int key) const override
Returns true if the collection contains an active property with the specified key.
void writePolygon(const QgsRingSequence &polygon, const QString &layer, const QString &hatchPattern, const QColor &color)
Draw dxf filled polygon (HATCH)
void renderPoint(QPointF point, QgsSymbolRenderContext &context) override
Renders a marker at the specified point.
#define DEFAULT_FONTMARKER_SIZE
QColor strokeColor() const override
Gets stroke color.
void setPenJoinStyle(Qt::PenJoinStyle style)
Sets the stroke join style.
static QgsSymbolLayer * createFromSld(QDomElement &element)
void setPath(const QString &path)
Set the marker SVG path.
QPainterPath mPath
Painter path representing shape. If mPolygon is empty then the shape is stored in mPath...
static QString encodeColor(const QColor &color)
Diagonal half square (bottom left half)
virtual void setColor(const QColor &color)
The fill color.
double angle() const
Returns the rotation angle for the marker, in degrees clockwise from north.
void startRender(QgsSymbolRenderContext &context) override
void markerOffset(QgsSymbolRenderContext &context, double &offsetX, double &offsetY) const
Calculates the required marker offset, including both the symbol offset and any displacement required...
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
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...
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for data defined symbology.
static QString encodePenStyle(Qt::PenStyle style)
Perform transforms between map coordinates and device coordinates.
static QgsSymbolLayer * create(const QgsStringMap &properties=QgsStringMap())
Creates a new QgsFilledMarkerSymbolLayer.
static QgsSymbolLayer * create(const QgsStringMap &properties=QgsStringMap())
Creates a new QgsSimpleMarkerSymbolLayer.
static QString svgSymbolPathToName(const QString &path, const QgsPathResolver &pathResolver)
Determines an SVG symbol's name from its path.
static double rescaleUom(double size, QgsUnitTypes::RenderUnit unit, const QgsStringMap &props)
Rescales the given size based on the uomScale found in the props, if any is found, otherwise returns the value un-modified.
One third circle (top left third)
void setStrokeWidthUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the stroke width.
Quarter circle (top left quarter)
QgsUnitTypes::DistanceUnit mapUnits() const
Retrieve map units.
QgsStringMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
void setStrokeColor(const QColor &color) override
Set stroke color.
void copyDataDefinedProperties(QgsSymbolLayer *destLayer) const
Copies all data defined properties of this layer to another symbol layer.
QgsUnitTypes::RenderUnit mOffsetUnit
Offset units.
double updateDefaultAspectRatio()
Calculates the default marker aspect ratio between width and height.
void setColor(const QColor &color) override
The fill color.
bool hasDataDefinedProperties() const override
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties...
void stopRender(QgsSymbolRenderContext &context) override
QgsSymbol::ScaleMethod scaleMethod() const
Returns the method to use for scaling the marker's size.
bool mUsingCache
True if using cached images of markers for drawing.
QPen mPen
QPen corresponding to marker's stroke style.
void setStrokeWidthMapUnitScale(const QgsMapUnitScale &scale)
Sets the map scale for the width of the marker's stroke.
#define DEFAULT_SCALE_METHOD
Q_GUI_EXPORT int qt_defaultDpiY()
virtual bool hasDataDefinedProperties() const
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties...
Calculate scale by the area.
double mStrokeWidth
Stroke width.
QBrush mBrush
QBrush corresponding to marker's fill style.
QgsSimpleMarkerSymbolLayerBase(QgsSimpleMarkerSymbolLayerBase::Shape shape=Circle, double size=DEFAULT_SIMPLEMARKER_SIZE, double angle=DEFAULT_SIMPLEMARKER_ANGLE, QgsSymbol::ScaleMethod scaleMethod=DEFAULT_SCALE_METHOD)
Constructor for QgsSimpleMarkerSymbolLayerBase.
void setHorizontalAnchorPoint(HorizontalAnchorPoint h)
Sets the horizontal anchor point for positioning the symbol.
static QgsSymbolLayer * create(const QgsStringMap &properties=QgsStringMap())
static void resolvePaths(QgsStringMap &properties, const QgsPathResolver &pathResolver, bool saving)
Turns relative paths in properties map to absolute when reading and vice versa when writing...
void setSizeMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the symbol's size.
#define DEFAULT_FONTMARKER_JOINSTYLE
bool forceVectorOutput() const
Returns TRUE if rendering operations should use vector operations instead of any faster raster shortc...
void setLayer(const QString &layer)
static double mapUnitScaleFactor(double scale, QgsUnitTypes::RenderUnit symbolUnits, QgsUnitTypes::DistanceUnit mapUnits, double mapUnitsPerPixel=1.0)
Returns scale factor for conversion to map units.
QColor color() const override
The fill color.
static void createRotationElement(QDomDocument &doc, QDomElement &element, const QString &rotationFunc)
void setFillColor(const QColor &color) override
Set fill color.
QColor fillColor() const override
Gets fill color.
#define DEFAULT_FONTMARKER_ANGLE
void setStrokeWidth(double w)
double mAngle
Marker rotation angle, in degrees clockwise from north.
QgsStringMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
void writeFilledCircle(const QString &layer, const QColor &color, const QgsPoint &pt, double radius)
Write filled circle (as hatch)
void setStrokeWidthUnit(QgsUnitTypes::RenderUnit unit)
Sets the stroke width unit.
double mapUnitsPerPixel() const
Returns current map units per pixel.
static double estimateMaxSymbolBleed(QgsSymbol *symbol, const QgsRenderContext &context)
Returns the maximum estimated bleed for the symbol.
static QgsSymbolLayer * create(const QgsStringMap &properties=QgsStringMap())
Creates a new QgsFontMarkerSymbolLayer from a property map (see properties())
QgsMapUnitScale mSizeMapUnitScale
Marker size map unit scale.
Character, eg for font marker symbol layers.
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 Q_INVOKABLE QgsUnitTypes::RenderUnit decodeRenderUnit(const QString &string, bool *ok=nullptr)
Decodes a render unit from a string.
QPen mSelPen
QPen to use as stroke of selected symbols.
QgsUnitTypes::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
QgsRenderContext & renderContext()
Returns a reference to the context's render context.
QgsSymbol * subSymbol() override
Returns the symbol's sub symbol, if present.
Point geometry type, with support for z-dimension and m-values.
static Qt::PenStyle decodePenStyle(const QString &str)
static bool externalGraphicFromSld(QDomElement &element, QString &path, QString &mime, QColor &color, double &size)
bool shapeToPolygon(Shape shape, QPolygonF &polygon) const
Creates a polygon representing the specified shape.
double strokeWidth() const
Returns the width of the marker's stroke.
QgsStringMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
void startRender(QgsSymbolRenderContext &context) override
void renderPoint(QPointF point, QgsSymbolRenderContext &context) override
Renders a marker at the specified point.
void setOutputUnit(QgsUnitTypes::RenderUnit unit) override
Sets 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.
HorizontalAnchorPoint
Symbol horizontal anchor points.
virtual void setStrokeColor(const QColor &color)
Set stroke color.
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...
VerticalAnchorPoint
Symbol vertical anchor points.
QgsFields fields() const
Fields of the layer.
static Q_INVOKABLE QString encodeUnit(QgsUnitTypes::DistanceUnit unit)
Encodes a distance unit to a string.
bool setPreservedAspectRatio(bool par)
Set preserved the marker aspect ratio between width and height.
QString layerType() const override
Returns a string that represents this layer type.
Q_GUI_EXPORT int qt_defaultDpiX()
virtual QColor fillColor() const
Gets fill color.
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
QgsExpressionContext & expressionContext()
Gets the expression context.
qreal opacity() const
Returns the opacity for the symbol.
QString layerType() const override
Returns a string that represents this layer type.
static QString encodeScaleMethod(QgsSymbol::ScaleMethod scaleMethod)
static bool externalMarkerFromSld(QDomElement &element, QString &path, QString &format, int &markIndex, QColor &color, double &size)
void startRender(QgsSymbolRenderContext &context) override
QVector< QgsPoint > QgsPointSequence
void stopRender(QgsSymbolRenderContext &context) override
void setFixedAspectRatio(double ratio)
Set the marker aspect ratio between width and height to be used in rendering, if the value set is low...
QVector< QgsPointSequence > QgsRingSequence
void containsParams(const QString &path, bool &hasFillParam, QColor &defaultFillColor, bool &hasStrokeParam, QColor &defaultStrokeColor, bool &hasStrokeWidthParam, double &defaultStrokeWidth) const
Tests if an svg file contains parameters for fill, stroke color, stroke width.
static QgsSymbolLayer * createFromSld(QDomElement &element)
Creates a new QgsFontMarkerSymbolLayer from an SLD XML element.
Qt::PenStyle strokeStyle() const
Returns the marker's stroke style (e.g., solid, dashed, etc)
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...
void setSizeUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the symbol's size.
Stroke style (eg solid, dashed)
#define DEFAULT_SIMPLEMARKER_BORDERCOLOR
double calculateAspectRatio(QgsSymbolRenderContext &context, double scaledSize, bool &hasDataDefinedAspectRatio) const
Calculates the marker aspect ratio between width and height.
Contains information about the context of a rendering operation.
Abstract base class for marker symbol layers.
void writeCircle(const QString &layer, const QColor &color, const QgsPoint &pt, double radius, const QString &lineStyleName, double width)
Write circle (as polyline)
void setShift(QPointF shift)
QPainter * painter()
Returns the destination QPainter for the render operation.
virtual void setFillColor(const QColor &color)
Set fill color.
QColor color() const override
The fill color.
QImage mCache
Cached image of marker, if using cached version.
QgsSvgMarkerSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
QgsSimpleMarkerSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
Struct for storing maximum and minimum scales for measurements in map units.
void setMapUnitScale(const QgsMapUnitScale &scale) override
#define DEFAULT_SIMPLEMARKER_ANGLE
#define DEFAULT_SIMPLEMARKER_COLOR
QgsStringMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
void startRender(QgsSymbolRenderContext &context) override
Shape
Marker symbol shapes.
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.
QgsSymbol::ScaleMethod mScaleMethod
Marker size scaling method.
Qt::PenJoinStyle mPenJoinStyle
Stroke pen join style.
virtual QSet< QString > usedAttributes(const QgsRenderContext &context) const
Returns the set of attributes referenced by the layer.
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...
~QgsFontMarkerSymbolLayer() override
bool hasGeometry() const
Returns true if the feature has an associated geometry.
QRectF bounds(QPointF point, QgsSymbolRenderContext &context) override
Returns the approximate bounding box of the marker symbol layer, taking into account any data defined...
QByteArray svgContent(const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth, double widthScaleFactor, double fixedAspectRatio=0)
Gets SVG content.
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer's subsymbol. takes ownership of the passed symbol.
const QgsFeature * feature() const
Current feature being rendered - may be null.
QColor fillColor() const override
Gets fill color.
HorizontalAnchorPoint mHorizontalAnchorPoint
Horizontal anchor point.
QImage mSelCache
Cached image of selected marker, if using cached version.
#define DEFAULT_FONTMARKER_CHR
void setStrokeWidthMapUnitScale(const QgsMapUnitScale &scale)
SymbolType type() const
Returns the symbol's type.
void writeSldMarker(QDomDocument &doc, QDomElement &element, const QgsStringMap &props) const override
Writes the symbol layer definition as a SLD XML element.
Flags flags() const
Returns combination of flags used for rendering.
void writeSldMarker(QDomDocument &doc, QDomElement &element, const QgsStringMap &props) const override
Writes the symbol layer definition as a SLD XML element.
static bool wellKnownMarkerFromSld(QDomElement &element, QString &name, QColor &color, QColor &strokeColor, Qt::PenStyle &strokeStyle, double &strokeWidth, double &size)
const QgsMapToPixel & mapToPixel() const
Returns the context's map to pixel transform, which transforms between map coordinates and device coo...
void setAngle(double angle)
Sets the rotation angle for the marker.
static QgsMapUnitScale decodeMapUnitScale(const QString &str)
QString layerType() const override
Returns a string that represents this layer type.
void stopRender(QgsSymbolRenderContext &context) override
Qt::PenJoinStyle penJoinStyle() const
Returns the marker's stroke join style (e.g., miter, bevel, 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 copyPaintEffect(QgsSymbolLayer *destLayer) const
Copies paint effect of this layer to another symbol layer.
QgsMapUnitScale mOffsetMapUnitScale
Offset map unit scale.
VerticalAnchorPoint mVerticalAnchorPoint
Vertical anchor point.
void stopRender(QgsSymbolRenderContext &context) override
void setFillColor(const QColor &color) override
Set fill color.
static bool shapeIsFilled(QgsSimpleMarkerSymbolLayerBase::Shape shape)
Returns true if a symbol shape has a fill.
static QString svgSymbolNameToPath(const QString &name, const QgsPathResolver &pathResolver)
Determines an SVG symbol's path from its name.
static QPointF _rotatedOffset(QPointF offset, double angle)
Adjusts a marker offset to account for rotation.
Shape mShape
Symbol shape.
bool prepareMarkerShape(Shape shape)
Prepares the layer for drawing the specified shape (QPolygonF version)
Resolves relative paths into absolute paths and vice versa.
void setMapUnitScale(const QgsMapUnitScale &scale) override
QString layerType() const override
Returns a string that represents this layer type.
QgsSimpleMarkerSymbolLayerBase::Shape shape() const
Returns the shape for the rendered marker symbol.
#define DEFAULT_SVGMARKER_SIZE
QgsFilledMarkerSymbolLayer(QgsSimpleMarkerSymbolLayerBase::Shape shape=Circle, double size=DEFAULT_SIMPLEMARKER_SIZE, double angle=DEFAULT_SIMPLEMARKER_ANGLE, QgsSymbol::ScaleMethod scaleMethod=DEFAULT_SCALE_METHOD)
Constructor for QgsFilledMarkerSymbolLayer.
Filled marker symbol layer, consisting of a shape which is rendered using a QgsFillSymbol.
const QgsPathResolver & pathResolver() const
Returns the path resolver for conversion between relative and absolute paths during rendering operati...
#define DEFAULT_SVGMARKER_ANGLE
virtual QColor color() const
The fill color.
QgsWkbTypes::GeometryType type() const
Returns type of the geometry as a QgsWkbTypes::GeometryType.
static void multiplyImageOpacity(QImage *image, qreal opacity)
Multiplies opacity of image pixel values with a (global) transparency value.
Rotated cross (lines only), "x" shape.
void setOutputUnit(QgsUnitTypes::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QPolygonF mPolygon
Polygon of points in shape. If polygon is empty then shape is using mPath.
QgsFilledMarkerSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
#define DEFAULT_FONTMARKER_FONT
static QString encodePenJoinStyle(Qt::PenJoinStyle style)
QgsPropertyCollection mDataDefinedProperties
bool prepareMarkerPath(Shape symbol)
Prepares the layer for drawing the specified shape (QPainterPath version)
QSizeF svgViewboxSize(const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth, double widthScaleFactor, double fixedAspectRatio=0)
Calculates the viewbox size of a (possibly cached) SVG file.
Quarter square (top left quarter)
RenderUnit
Rendering size units.
static QColor decodeColor(const QString &str)
void setOutputSize(const QRectF &r)
void setVerticalAnchorPoint(VerticalAnchorPoint v)
Sets the vertical anchor point for positioning the symbol.
QRectF bounds(QPointF point, QgsSymbolRenderContext &context) override
Returns the approximate bounding box of the marker symbol layer, taking into account any data defined...