21 #include "qgsexpression.h" 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" ) );
1210 Q_UNUSED( context );
1218 p->drawPath(
mPath );
1231 if ( hasDataDefinedSize )
1241 size = std::sqrt( size );
1252 size *= mmMapUnitScaleFactor;
1254 double halfSize = size / 2.0;
1266 strokeWidth *= mmMapUnitScaleFactor;
1270 QColor pc =
mPen.color();
1271 QColor bc =
mBrush.color();
1288 QPointF off( offsetX, offsetY );
1317 off *= mmMapUnitScaleFactor;
1321 t.translate( shift.x() + offsetX, shift.y() + offsetY );
1329 t.scale( halfSize, -halfSize );
1331 polygon = t.map( polygon );
1334 p.reserve( polygon.size() );
1335 for (
int i = 0; i < polygon.size(); i++ )
1339 if (
mBrush.style() != Qt::NoBrush )
1341 if (
mPen.style() != Qt::NoPen )
1342 e.
writePolyline( p, layerName, QStringLiteral(
"CONTINUOUS" ), pc, strokeWidth );
1344 else if ( shape ==
Circle )
1346 if (
mBrush.style() != Qt::NoBrush )
1348 if (
mPen.style() != Qt::NoPen )
1349 e.
writeCircle( layerName, pc,
QgsPoint( shift ), halfSize, QStringLiteral(
"CONTINUOUS" ), strokeWidth );
1351 else if ( shape ==
Line )
1353 QPointF pt1 = t.map( QPointF( 0, -halfSize ) );
1354 QPointF pt2 = t.map( QPointF( 0, halfSize ) );
1356 if (
mPen.style() != Qt::NoPen )
1359 else if ( shape ==
Cross )
1361 if (
mPen.style() != Qt::NoPen )
1363 QPointF pt1 = t.map( QPointF( -halfSize, 0 ) );
1364 QPointF pt2 = t.map( QPointF( halfSize, 0 ) );
1365 QPointF pt3 = t.map( QPointF( 0, -halfSize ) );
1366 QPointF pt4 = t.map( QPointF( 0, halfSize ) );
1372 else if ( shape ==
Cross2 )
1374 if (
mPen.style() != Qt::NoPen )
1376 QPointF pt1 = t.map( QPointF( -halfSize, -halfSize ) );
1377 QPointF pt2 = t.map( QPointF( halfSize, halfSize ) );
1378 QPointF pt3 = t.map( QPointF( halfSize, -halfSize ) );
1379 QPointF pt4 = t.map( QPointF( -halfSize, halfSize ) );
1387 if (
mPen.style() != Qt::NoPen )
1389 QPointF pt1 = t.map( QPointF( -halfSize, halfSize ) );
1390 QPointF pt2 = t.map( QPointF( 0, 0 ) );
1391 QPointF pt3 = t.map( QPointF( -halfSize, -halfSize ) );
1442 double penWidth = 0.0;
1457 if ( ok && strokeStyle == QLatin1String(
"no" ) )
1466 symbolBounds.adjust( -penWidth / 2.0, -penWidth / 2.0,
1467 penWidth / 2.0, penWidth / 2.0 );
1469 return symbolBounds;
1516 if ( props.contains( QStringLiteral(
"name" ) ) )
1517 name = props[QStringLiteral(
"name" )];
1518 if ( props.contains( QStringLiteral(
"size" ) ) )
1519 size = props[QStringLiteral(
"size" )].toDouble();
1520 if ( props.contains( QStringLiteral(
"angle" ) ) )
1521 angle = props[QStringLiteral(
"angle" )].toDouble();
1522 if ( props.contains( QStringLiteral(
"scale_method" ) ) )
1526 if ( props.contains( QStringLiteral(
"offset" ) ) )
1528 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
1530 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
1532 if ( props.contains( QStringLiteral(
"size_unit" ) ) )
1534 if ( props.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
1536 if ( props.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
1540 if ( props.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
1554 return QStringLiteral(
"FilledMarker" );
1579 map[QStringLiteral(
"size" )] = QString::number(
mSize );
1582 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
1615 mFill.reset( static_cast<QgsFillSymbol *>( symbol ) );
1638 attr.unite( mFill->usedAttributes( context ) );
1646 mFill->setColor( c );
1651 return mFill ? mFill->color() :
mColor;
1667 p->setBrush( Qt::red );
1671 p->setBrush( Qt::NoBrush );
1673 p->setPen( Qt::black );
1675 if ( !polygon.isEmpty() )
1681 QPolygonF poly = path.toFillPolygon();
1701 mColor = QColor( 35, 35, 35 );
1702 mStrokeColor = QColor( 35, 35, 35 );
1703 updateDefaultAspectRatio();
1714 if ( props.contains( QStringLiteral(
"name" ) ) )
1715 name = props[QStringLiteral(
"name" )];
1716 if ( props.contains( QStringLiteral(
"size" ) ) )
1717 size = props[QStringLiteral(
"size" )].toDouble();
1718 if ( props.contains( QStringLiteral(
"angle" ) ) )
1719 angle = props[QStringLiteral(
"angle" )].toDouble();
1720 if ( props.contains( QStringLiteral(
"scale_method" ) ) )
1726 if ( !props.contains( QStringLiteral(
"fill" ) ) && !props.contains( QStringLiteral(
"color" ) ) && !props.contains( QStringLiteral(
"outline" ) ) &&
1727 !props.contains( QStringLiteral(
"outline_color" ) ) && !props.contains( QStringLiteral(
"outline-width" ) ) && !props.contains( QStringLiteral(
"outline_width" ) ) )
1730 double fillOpacity = 1.0;
1731 double strokeOpacity = 1.0;
1733 bool hasFillParam =
false, hasFillOpacityParam =
false, hasStrokeParam =
false, hasStrokeWidthParam =
false, hasStrokeOpacityParam =
false;
1734 bool hasDefaultFillColor =
false, hasDefaultFillOpacity =
false, hasDefaultStrokeColor =
false, hasDefaultStrokeWidth =
false, hasDefaultStrokeOpacity =
false;
1736 hasFillOpacityParam, hasDefaultFillOpacity, fillOpacity,
1737 hasStrokeParam, hasDefaultStrokeColor, strokeColor,
1738 hasStrokeWidthParam, hasDefaultStrokeWidth, strokeWidth,
1739 hasStrokeOpacityParam, hasDefaultStrokeOpacity, strokeOpacity );
1740 if ( hasDefaultFillColor )
1744 if ( hasDefaultFillOpacity )
1747 c.setAlphaF( fillOpacity );
1750 if ( hasDefaultStrokeColor )
1754 if ( hasDefaultStrokeWidth )
1758 if ( hasDefaultStrokeOpacity )
1761 c.setAlphaF( strokeOpacity );
1766 if ( props.contains( QStringLiteral(
"size_unit" ) ) )
1768 if ( props.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
1770 if ( props.contains( QStringLiteral(
"fixedAspectRatio" ) ) )
1772 if ( props.contains( QStringLiteral(
"offset" ) ) )
1774 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
1776 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
1778 if ( props.contains( QStringLiteral(
"fill" ) ) )
1783 else if ( props.contains( QStringLiteral(
"color" ) ) )
1787 if ( props.contains( QStringLiteral(
"outline" ) ) )
1792 else if ( props.contains( QStringLiteral(
"outline_color" ) ) )
1796 else if ( props.contains( QStringLiteral(
"line_color" ) ) )
1801 if ( props.contains( QStringLiteral(
"outline-width" ) ) )
1804 m->
setStrokeWidth( props[QStringLiteral(
"outline-width" )].toDouble() );
1806 else if ( props.contains( QStringLiteral(
"outline_width" ) ) )
1808 m->
setStrokeWidth( props[QStringLiteral(
"outline_width" )].toDouble() );
1810 else if ( props.contains( QStringLiteral(
"line_width" ) ) )
1812 m->
setStrokeWidth( props[QStringLiteral(
"line_width" )].toDouble() );
1815 if ( props.contains( QStringLiteral(
"outline_width_unit" ) ) )
1819 else if ( props.contains( QStringLiteral(
"line_width_unit" ) ) )
1823 if ( props.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
1826 if ( props.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
1830 if ( props.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
1844 QgsStringMap::iterator it = properties.find( QStringLiteral(
"name" ) );
1845 if ( it != properties.end() )
1857 QColor defaultFillColor, defaultStrokeColor;
1858 double strokeWidth, fillOpacity, strokeOpacity;
1859 bool hasFillParam =
false, hasFillOpacityParam =
false, hasStrokeParam =
false, hasStrokeWidthParam =
false, hasStrokeOpacityParam =
false;
1860 bool hasDefaultFillColor =
false, hasDefaultFillOpacity =
false, hasDefaultStrokeColor =
false, hasDefaultStrokeWidth =
false, hasDefaultStrokeOpacity =
false;
1862 hasFillOpacityParam, hasDefaultFillOpacity, fillOpacity,
1863 hasStrokeParam, hasDefaultStrokeColor, defaultStrokeColor,
1864 hasStrokeWidthParam, hasDefaultStrokeWidth, strokeWidth,
1865 hasStrokeOpacityParam, hasDefaultStrokeOpacity, strokeOpacity );
1867 double newFillOpacity = hasFillOpacityParam ?
fillColor().alphaF() : 1.0;
1868 double newStrokeOpacity = hasStrokeOpacityParam ?
strokeColor().alphaF() : 1.0;
1870 if ( hasDefaultFillColor )
1872 defaultFillColor.setAlphaF( newFillOpacity );
1875 if ( hasDefaultFillOpacity )
1878 c.setAlphaF( fillOpacity );
1881 if ( hasDefaultStrokeColor )
1883 defaultStrokeColor.setAlphaF( newStrokeOpacity );
1886 if ( hasDefaultStrokeWidth )
1888 setStrokeWidth( strokeWidth );
1890 if ( hasDefaultStrokeOpacity )
1893 c.setAlphaF( strokeOpacity );
1897 updateDefaultAspectRatio();
1902 if ( mDefaultAspectRatio == 0.0 )
1907 double widthScaleFactor = 3.465;
1910 mDefaultAspectRatio = svgViewbox.isValid() ? svgViewbox.height() / svgViewbox.width() : 0.0;
1912 return mDefaultAspectRatio;
1917 bool aPreservedAspectRatio = preservedAspectRatio();
1918 if ( aPreservedAspectRatio && !par )
1920 mFixedAspectRatio = mDefaultAspectRatio;
1922 else if ( !aPreservedAspectRatio && par )
1924 mFixedAspectRatio = 0.0;
1926 return preservedAspectRatio();
1932 return QStringLiteral(
"SvgMarker" );
1938 Q_UNUSED( context );
1943 Q_UNUSED( context );
1952 bool hasDataDefinedSize =
false;
1953 double scaledSize =
calculateSize( context, hasDataDefinedSize );
1957 if ( static_cast< int >( size ) < 1 || 10000.0 < size )
1964 bool hasDataDefinedAspectRatio =
false;
1965 double aspectRatio = calculateAspectRatio( context, scaledSize, hasDataDefinedAspectRatio );
1967 QPointF outputOffset;
1971 p->translate( point + outputOffset );
1977 QString path =
mPath;
1985 double strokeWidth = mStrokeWidth;
2007 bool fitsInCache =
true;
2008 bool usePict =
true;
2009 double hwRatio = 1.0;
2015 if ( fitsInCache && img.width() > 1 )
2020 QImage transparentImage = img.copy();
2022 p->drawImage( -transparentImage.width() / 2.0, -transparentImage.height() / 2.0, transparentImage );
2023 hwRatio =
static_cast< double >( transparentImage.height() ) / static_cast< double >( transparentImage.width() );
2027 p->drawImage( -img.width() / 2.0, -img.height() / 2.0, img );
2028 hwRatio =
static_cast< double >( img.height() ) / static_cast< double >( img.width() );
2033 if ( usePict || !fitsInCache )
2035 p->setOpacity( context.
opacity() );
2038 if ( pct.width() > 1 )
2041 _fixQPictureDPI( p );
2042 p->drawPicture( 0, 0, pct );
2044 hwRatio =
static_cast< double >( pct.height() ) / static_cast< double >( pct.width() );
2052 if ( penWidth > size / 20 )
2055 penWidth = size / 20;
2057 double penOffset = penWidth / 2;
2058 pen.setWidth( penWidth );
2060 p->setBrush( Qt::NoBrush );
2061 double wSize = size + penOffset;
2062 double hSize = size * hwRatio + penOffset;
2063 p->drawRect( QRectF( -wSize / 2.0, -hSize / 2.0, wSize, hSize ) );
2071 p->setRenderHint( QPainter::Antialiasing );
2076 double QgsSvgMarkerSymbolLayer::calculateSize(
QgsSymbolRenderContext &context,
bool &hasDataDefinedSize )
const 2078 double scaledSize =
mSize;
2082 if ( hasDataDefinedSize )
2090 if ( hasDataDefinedSize )
2097 if ( hasDataDefinedSize && ok )
2102 scaledSize = std::sqrt( scaledSize );
2115 if ( !hasDataDefinedAspectRatio )
2116 return mFixedAspectRatio;
2121 double scaledAspectRatio = mDefaultAspectRatio;
2122 if ( mFixedAspectRatio > 0.0 )
2123 scaledAspectRatio = mFixedAspectRatio;
2125 double defaultHeight =
mSize * scaledAspectRatio;
2126 scaledAspectRatio = defaultHeight / scaledSize;
2129 double scaledHeight = scaledSize * scaledAspectRatio;
2136 if ( hasDataDefinedAspectRatio && ok )
2141 scaledHeight = sqrt( scaledHeight );
2148 scaledAspectRatio = scaledHeight / scaledSize;
2150 return scaledAspectRatio;
2158 markerOffset( context, scaledSize, scaledSize, offsetX, offsetY );
2159 offset = QPointF( offsetX, offsetY );
2169 if ( hasDataDefinedRotation )
2195 map[QStringLiteral(
"name" )] =
mPath;
2196 map[QStringLiteral(
"size" )] = QString::number(
mSize );
2199 map[QStringLiteral(
"fixedAspectRatio" )] = QString::number( mFixedAspectRatio );
2200 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
2207 map[QStringLiteral(
"outline_width" )] = QString::number( mStrokeWidth );
2239 mStrokeWidthUnit = unit;
2245 if ( unit != mStrokeWidthUnit )
2255 mStrokeWidthMapUnitScale = scale;
2262 return mStrokeWidthMapUnitScale;
2270 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
2271 element.appendChild( graphicElem );
2281 double angle = props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toDouble( &ok );
2284 angleFunc = QStringLiteral(
"%1 + %2" ).arg( props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ) ).arg(
mAngle );
2288 angleFunc = QString::number( angle +
mAngle );
2302 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
2303 if ( graphicElem.isNull() )
2306 QString path, mimeType;
2313 QString uom = element.attribute( QStringLiteral(
"uom" ) );
2316 if ( mimeType != QLatin1String(
"image/svg+xml" ) )
2324 double d = angleFunc.toDouble( &ok );
2344 Q_UNUSED( layerName );
2353 if ( hasDataDefinedSize )
2359 if ( hasDataDefinedSize && ok )
2364 size = std::sqrt( size );
2373 size *= mmMapUnitScaleFactor;
2376 double halfSize = size / 2.0;
2388 double offsetX = offset.x();
2389 double offsetY = offset.y();
2392 offsetX *= mmMapUnitScaleFactor;
2393 offsetY *= mmMapUnitScaleFactor;
2396 QPointF outputOffset( offsetX, offsetY );
2408 QString path =
mPath;
2416 double strokeWidth = mStrokeWidth;
2444 QSvgRenderer r( svgContent );
2457 p.translate( r.defaultSize().width() / 2.0, r.defaultSize().height() / 2.0 );
2459 p.translate( -r.defaultSize().width() / 2.0, -r.defaultSize().height() / 2.0 );
2462 pd.
setOutputSize( QRectF( -halfSize, -halfSize, size, size ) );
2471 bool hasDataDefinedSize =
false;
2472 double scaledSize =
calculateSize( context, hasDataDefinedSize );
2476 if ( static_cast< int >( scaledSize ) < 1 || 10000.0 < scaledSize )
2481 QPointF outputOffset;
2485 QString path =
mPath;
2493 double strokeWidth = mStrokeWidth;
2519 double scaledHeight = svgViewbox.isValid() ? scaledSize * svgViewbox.height() / svgViewbox.width() : scaledSize;
2524 transform.translate( point.x() + outputOffset.x(), point.y() + outputOffset.y() );
2527 transform.rotate( angle );
2530 strokeWidth += 1.0 / 2.0;
2532 QRectF symbolBounds = transform.mapRect( QRectF( -scaledSize / 2.0,
2533 -scaledHeight / 2.0,
2538 symbolBounds.adjust( -strokeWidth / 2.0, -strokeWidth / 2.0,
2539 strokeWidth / 2.0, strokeWidth / 2.0 );
2541 return symbolBounds;
2549 mFontFamily = fontFamily;
2554 mOrigSize = pointSize;
2566 delete mFontMetrics;
2577 if ( props.contains( QStringLiteral(
"font" ) ) )
2578 fontFamily = props[QStringLiteral(
"font" )];
2579 if ( props.contains( QStringLiteral(
"chr" ) ) && props[QStringLiteral(
"chr" )].length() > 0 )
2580 chr = props[QStringLiteral(
"chr" )].at( 0 );
2581 if ( props.contains( QStringLiteral(
"size" ) ) )
2582 pointSize = props[QStringLiteral(
"size" )].toDouble();
2583 if ( props.contains( QStringLiteral(
"color" ) ) )
2585 if ( props.contains( QStringLiteral(
"angle" ) ) )
2586 angle = props[QStringLiteral(
"angle" )].toDouble();
2590 if ( props.contains( QStringLiteral(
"outline_color" ) ) )
2592 if ( props.contains( QStringLiteral(
"outline_width" ) ) )
2593 m->
setStrokeWidth( props[QStringLiteral(
"outline_width" )].toDouble() );
2594 if ( props.contains( QStringLiteral(
"offset" ) ) )
2596 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
2598 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
2600 if ( props.contains( QStringLiteral(
"size_unit" ) ) )
2602 if ( props.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
2604 if ( props.contains( QStringLiteral(
"outline_width_unit" ) ) )
2606 if ( props.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
2608 if ( props.contains( QStringLiteral(
"joinstyle" ) ) )
2610 if ( props.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
2612 if ( props.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
2622 return QStringLiteral(
"FontMarker" );
2627 QColor brushColor =
mColor;
2628 QColor penColor = mStrokeColor;
2630 brushColor.setAlphaF(
mColor.alphaF() * context.
opacity() );
2631 penColor.setAlphaF( mStrokeColor.alphaF() * context.
opacity() );
2633 mBrush = QBrush( brushColor );
2634 mPen = QPen( penColor );
2635 mPen.setJoinStyle( mPenJoinStyle );
2638 mFont = QFont( mFontFamily );
2640 delete mFontMetrics;
2641 mFontMetrics =
new QFontMetrics( mFont );
2642 mChrWidth = mFontMetrics->width( mChr );
2643 mChrOffset = QPointF( mChrWidth / 2.0, -mFontMetrics->ascent() / 2.0 );
2649 Q_UNUSED( context );
2652 QString QgsFontMarkerSymbolLayer::characterToRender(
QgsSymbolRenderContext &context, QPointF &charOffset,
double &charWidth )
2654 charOffset = mChrOffset;
2655 QString charToRender = mChr;
2660 if ( charToRender != mChr )
2662 charWidth = mFontMetrics->width( charToRender );
2663 charOffset = QPointF( charWidth / 2.0, -mFontMetrics->ascent() / 2.0 );
2666 return charToRender;
2671 bool &hasDataDefinedRotation,
2673 double &angle )
const 2678 markerOffset( context, scaledSize, scaledSize, offsetX, offsetY );
2679 offset = QPointF( offsetX, offsetY );
2684 bool usingDataDefinedRotation =
false;
2689 usingDataDefinedRotation = ok;
2693 if ( hasDataDefinedRotation )
2717 double scaledSize =
mSize;
2721 if ( hasDataDefinedSize )
2727 if ( hasDataDefinedSize && ok )
2732 scaledSize = std::sqrt( scaledSize );
2747 QTransform transform;
2750 QColor brushColor =
mColor;
2757 brushColor.setAlphaF( brushColor.alphaF() * context.
opacity() );
2758 mBrush.setColor( brushColor );
2760 QColor penColor = mStrokeColor;
2766 penColor.setAlphaF( penColor.alphaF() * context.
opacity() );
2789 p->setBrush( mBrush );
2792 mPen.setColor( penColor );
2793 mPen.setWidthF( penWidth );
2798 p->setPen( Qt::NoPen );
2802 QPointF chrOffset = mChrOffset;
2804 QString charToRender = characterToRender( context, chrOffset, chrWidth );
2808 bool hasDataDefinedRotation =
false;
2813 transform.translate( point.x() + offset.x(), point.y() + offset.y() );
2816 transform.rotate( angle );
2820 double s = sizeToRender / mOrigSize;
2821 transform.scale( s, s );
2825 path.addText( -chrOffset.x(), -chrOffset.y(), mFont, charToRender );
2826 p->drawPath( transform.map( path ) );
2833 props[QStringLiteral(
"font" )] = mFontFamily;
2834 props[QStringLiteral(
"chr" )] = mChr;
2835 props[QStringLiteral(
"size" )] = QString::number(
mSize );
2840 props[QStringLiteral(
"outline_width" )] = QString::number( mStrokeWidth );
2844 props[QStringLiteral(
"angle" )] = QString::number(
mAngle );
2876 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
2877 element.appendChild( graphicElem );
2879 QString fontPath = QStringLiteral(
"ttf://%1" ).arg( mFontFamily );
2880 int markIndex = mChr.unicode();
2887 double angle = props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toDouble( &ok );
2890 angleFunc = QStringLiteral(
"%1 + %2" ).arg( props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ) ).arg(
mAngle );
2894 angleFunc = QString::number( angle +
mAngle );
2905 QPointF chrOffset = mChrOffset;
2906 double chrWidth = mChrWidth;
2908 ( void )characterToRender( context, chrOffset, chrWidth );
2910 if ( !mFontMetrics )
2911 mFontMetrics =
new QFontMetrics( mFont );
2916 chrWidth *= scaledSize / mOrigSize;
2919 bool hasDataDefinedRotation =
false;
2928 transform.translate( point.x() + offset.x(), point.y() + offset.y() );
2931 transform.rotate( angle );
2933 QRectF symbolBounds = transform.mapRect( QRectF( -chrWidth / 2.0,
2937 return symbolBounds;
2944 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
2945 if ( graphicElem.isNull() )
2948 QString name, format;
2956 if ( !name.startsWith( QLatin1String(
"ttf://" ) ) || format != QLatin1String(
"ttf" ) )
2959 QString fontFamily = name.mid( 6 );
2966 double d = angleFunc.toDouble( &ok );
2974 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)
Get SVG as QPicture&.
#define DEFAULT_SIMPLEMARKER_SIZE
QgsMapUnitScale mapUnitScale() const override
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
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...
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.
const QgsPathResolver & pathResolver() const
Returns the path resolver for conversion between relative and absolute paths during rendering operati...
static QgsSymbol::ScaleMethod decodeScaleMethod(const QString &str)
void setStrokeWidthMapUnitScale(const QgsMapUnitScale &scale)
Set 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.
QgsFields fields() const
Fields of the layer.
QgsUnitTypes::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
static QString svgSymbolPathToName(QString path, const QgsPathResolver &pathResolver)
Get SVG symbols's name from its path.
Qt::PenStyle mStrokeStyle
Stroke style.
Calculate scale by the diameter.
A paint device for drawing into dxf files.
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...
#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)
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.
QImage svgAsImage(const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth, double widthScaleFactor, bool &fitsInCache, double fixedAspectRatio=0)
Get 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.
Right facing arrow head (unfilled, lines only)
static QgsFillSymbol * createSimple(const QgsStringMap &properties)
Create a fill symbol with one symbol layer: SimpleFill with specified properties. ...
void startRender(QgsSymbolRenderContext &context) override
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)
QgsUnitTypes::RenderUnit mSizeUnit
Marker size unit.
virtual QColor strokeColor() const
Get stroke color.
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 copyPaintEffect(QgsSymbolLayer *destLayer) const
Copies paint effect of this layer to another symbol layer.
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 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
Flags flags() const
Return combination of flags used for rendering.
QgsUnitTypes::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
static QString svgSymbolNameToPath(QString name, const QgsPathResolver &pathResolver)
Get SVG symbol's path from its name.
QPointF mOffset
Marker offset.
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
bool hasGeometry() const
Returns true if the feature has an associated geometry.
static QString encodeShape(QgsSimpleMarkerSymbolLayerBase::Shape shape)
Encodes a shape to its string representation.
QgsMapUnitScale mapUnitScale() const override
QMap< QString, QString > QgsStringMap
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)
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
Compare two doubles (but allow some difference)
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.
double mapRotation() const
Return current map rotation in degrees.
#define DEFAULT_FONTMARKER_SIZE
QColor strokeColor() const override
Get stroke color.
void setPenJoinStyle(Qt::PenJoinStyle style)
Set stroke join style.
double strokeWidth() const
Returns the width of the marker's stroke.
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.
void startRender(QgsSymbolRenderContext &context) override
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 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)
QgsStringMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
bool shapeToPolygon(Shape shape, QPolygonF &polygon) const
Creates a polygon representing the specified shape.
void setStrokeColor(const QColor &color) override
Set stroke color.
double angle() const
Returns the rotation angle for the marker, in degrees clockwise from north.
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.
void stopRender(QgsSymbolRenderContext &context) override
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()
double calculateSize(QgsSymbolRenderContext &context, bool &hasDataDefinedSize) const
Calculates the desired size of the marker, considering data defined size overrides.
Calculate scale by the area.
qreal opacity() const
Returns the opacity for the symbol.
double size() const
Returns the symbol size.
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
void setLayer(const QString &layer)
QColor color() const override
The fill color.
void calculateOffsetAndRotation(QgsSymbolRenderContext &context, double scaledSize, bool &hasDataDefinedRotation, QPointF &offset, double &angle) const
Calculates the marker offset and rotation.
virtual QColor color() const
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
Get fill color.
QColor selectionColor() const
#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)
Set stroke width unit.
double calculateAspectRatio(QgsSymbolRenderContext &context, double scaledSize, bool &hasDataDefinedAspectRatio) const
Calculates the marker aspect ratio between width and height.
void markerOffset(QgsSymbolRenderContext &context, double &offsetX, double &offsetY) const
Calculates the required marker offset, including both the symbol offset and any displacement required...
static double estimateMaxSymbolBleed(QgsSymbol *symbol, const QgsRenderContext &context)
Returns the maximum estimated bleed for the symbol.
static QgsSymbolLayer * create(const QgsStringMap &properties=QgsStringMap())
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...
Qt::PenJoinStyle penJoinStyle() const
Returns the marker's stroke join style (e.g., miter, bevel, etc).
static Q_INVOKABLE QgsUnitTypes::RenderUnit decodeRenderUnit(const QString &string, bool *ok=nullptr)
Decodes a render unit from a string.
QgsSimpleMarkerSymbolLayerBase::Shape shape() const
Returns the shape for the rendered marker symbol.
QgsGeometry geometry() const
Returns the geometry associated with this feature.
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)
QgsWkbTypes::GeometryType type() const
Returns type of the geometry as a QgsWkbTypes::GeometryType.
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.
Qt::PenStyle strokeStyle() const
Returns the marker's stroke style (e.g., solid, dashed, etc)
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.
VerticalAnchorPoint
Symbol vertical anchor points.
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()
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
QgsSymbol::ScaleMethod scaleMethod() const
Returns the method to use for scaling the marker's size.
QgsExpressionContext & expressionContext()
Gets the expression context.
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.
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
bool forceVectorOutput() const
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
static QgsSymbolLayer * createFromSld(QDomElement &element)
void setSizeUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the symbol's size.
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...
Stroke style (eg solid, dashed)
#define DEFAULT_SIMPLEMARKER_BORDERCOLOR
virtual QSet< QString > usedAttributes(const QgsRenderContext &context) const
Returns the set of attributes referenced by the layer.
Contains information about the context of a rendering operation.
Abstract base class for marker symbol layers.
double convertToPainterUnits(double size, QgsUnitTypes::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale()) const
Converts a size from the specified units to painter units (pixels).
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.
const QgsMapToPixel & mapToPixel() const
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.
const QgsFeature * feature() const
Current feature being rendered - may be null.
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
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)
Get SVG content.
bool setSubSymbol(QgsSymbol *symbol) override
set layer's subsymbol. takes ownership of the passed symbol
QColor fillColor() const override
Get 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)
void writeSldMarker(QDomDocument &doc, QDomElement &element, const QgsStringMap &props) const override
Writes the symbol layer definition as a SLD XML element.
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)
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
bool writeDxf(QgsDxfExport &e, double mmMapUnitScaleFactor, const QString &layerName, QgsSymbolRenderContext &context, QPointF shift=QPointF(0.0, 0.0)) const override
write as DXF
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 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.
#define DEFAULT_SVGMARKER_SIZE
QPointF offset() const
Returns the marker's offset, which is the horizontal and vertical displacement which the rendered mar...
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.
double scaleFactor() const
Returns the scaling factor for the render to convert painter units to physical sizes.
virtual QColor fillColor() const
Get fill color.
#define DEFAULT_SVGMARKER_ANGLE
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 copyDataDefinedProperties(QgsSymbolLayer *destLayer) const
Copies all data defined properties of this layer to another symbol layer.
void setOutputSize(const QRectF &r)
void setVerticalAnchorPoint(VerticalAnchorPoint v)
Sets the vertical anchor point for positioning the symbol.
QgsSymbol::RenderHints renderHints() const
Returns the rendering hint flags for 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...