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 );
1224 Q_UNUSED( mmMapUnitScaleFactor );
1233 if ( hasDataDefinedSize )
1242 size = std::sqrt( size );
1255 double halfSize = size / 2.0;
1272 QColor pc =
mPen.color();
1273 QColor bc =
mBrush.color();
1293 QPointF off( offsetX, offsetY );
1322 t.translate( shift.x() + off.x(), shift.y() - off.y() );
1330 t.scale( halfSize, -halfSize );
1332 polygon = t.map( polygon );
1335 p.reserve( polygon.size() );
1336 for (
int i = 0; i < polygon.size(); i++ )
1341 if (
mBrush.style() != Qt::NoBrush )
1343 if (
mPen.style() != Qt::NoPen )
1344 e.
writePolyline( p, layerName, QStringLiteral(
"CONTINUOUS" ), pc, strokeWidth );
1346 else if ( shape ==
Circle )
1348 shift += QPointF( off.x(), -off.y() );
1349 if (
mBrush.style() != Qt::NoBrush )
1351 if (
mPen.style() != Qt::NoPen )
1352 e.
writeCircle( layerName, pc,
QgsPoint( shift ), halfSize, QStringLiteral(
"CONTINUOUS" ), strokeWidth );
1354 else if ( shape ==
Line )
1356 QPointF pt1 = t.map( QPointF( 0, -halfSize ) );
1357 QPointF pt2 = t.map( QPointF( 0, halfSize ) );
1359 if (
mPen.style() != Qt::NoPen )
1362 else if ( shape ==
Cross )
1364 if (
mPen.style() != Qt::NoPen )
1366 QPointF pt1 = t.map( QPointF( -halfSize, 0 ) );
1367 QPointF pt2 = t.map( QPointF( halfSize, 0 ) );
1368 QPointF pt3 = t.map( QPointF( 0, -halfSize ) );
1369 QPointF pt4 = t.map( QPointF( 0, halfSize ) );
1375 else if ( shape ==
Cross2 )
1377 if (
mPen.style() != Qt::NoPen )
1379 QPointF pt1 = t.map( QPointF( -halfSize, -halfSize ) );
1380 QPointF pt2 = t.map( QPointF( halfSize, halfSize ) );
1381 QPointF pt3 = t.map( QPointF( halfSize, -halfSize ) );
1382 QPointF pt4 = t.map( QPointF( -halfSize, halfSize ) );
1390 if (
mPen.style() != Qt::NoPen )
1392 QPointF pt1 = t.map( QPointF( -halfSize, halfSize ) );
1393 QPointF pt2 = t.map( QPointF( 0, 0 ) );
1394 QPointF pt3 = t.map( QPointF( -halfSize, -halfSize ) );
1445 double penWidth = 0.0;
1460 if ( ok && strokeStyle == QLatin1String(
"no" ) )
1469 symbolBounds.adjust( -penWidth / 2.0, -penWidth / 2.0,
1470 penWidth / 2.0, penWidth / 2.0 );
1472 return symbolBounds;
1519 if ( props.contains( QStringLiteral(
"name" ) ) )
1520 name = props[QStringLiteral(
"name" )];
1521 if ( props.contains( QStringLiteral(
"size" ) ) )
1522 size = props[QStringLiteral(
"size" )].toDouble();
1523 if ( props.contains( QStringLiteral(
"angle" ) ) )
1524 angle = props[QStringLiteral(
"angle" )].toDouble();
1525 if ( props.contains( QStringLiteral(
"scale_method" ) ) )
1529 if ( props.contains( QStringLiteral(
"offset" ) ) )
1531 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
1533 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
1535 if ( props.contains( QStringLiteral(
"size_unit" ) ) )
1537 if ( props.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
1539 if ( props.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
1543 if ( props.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
1557 return QStringLiteral(
"FilledMarker" );
1582 map[QStringLiteral(
"size" )] = QString::number(
mSize );
1585 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
1618 mFill.reset( static_cast<QgsFillSymbol *>( symbol ) );
1641 attr.unite( mFill->usedAttributes( context ) );
1649 mFill->setColor( c );
1654 return mFill ? mFill->color() :
mColor;
1670 p->setBrush( Qt::red );
1674 p->setBrush( Qt::NoBrush );
1676 p->setPen( Qt::black );
1678 if ( !polygon.isEmpty() )
1684 QPolygonF poly = path.toFillPolygon();
1704 mColor = QColor( 35, 35, 35 );
1705 mStrokeColor = QColor( 35, 35, 35 );
1706 updateDefaultAspectRatio();
1717 if ( props.contains( QStringLiteral(
"name" ) ) )
1718 name = props[QStringLiteral(
"name" )];
1719 if ( props.contains( QStringLiteral(
"size" ) ) )
1720 size = props[QStringLiteral(
"size" )].toDouble();
1721 if ( props.contains( QStringLiteral(
"angle" ) ) )
1722 angle = props[QStringLiteral(
"angle" )].toDouble();
1723 if ( props.contains( QStringLiteral(
"scale_method" ) ) )
1729 if ( !props.contains( QStringLiteral(
"fill" ) ) && !props.contains( QStringLiteral(
"color" ) ) && !props.contains( QStringLiteral(
"outline" ) ) &&
1730 !props.contains( QStringLiteral(
"outline_color" ) ) && !props.contains( QStringLiteral(
"outline-width" ) ) && !props.contains( QStringLiteral(
"outline_width" ) ) )
1733 double fillOpacity = 1.0;
1734 double strokeOpacity = 1.0;
1736 bool hasFillParam =
false, hasFillOpacityParam =
false, hasStrokeParam =
false, hasStrokeWidthParam =
false, hasStrokeOpacityParam =
false;
1737 bool hasDefaultFillColor =
false, hasDefaultFillOpacity =
false, hasDefaultStrokeColor =
false, hasDefaultStrokeWidth =
false, hasDefaultStrokeOpacity =
false;
1739 hasFillOpacityParam, hasDefaultFillOpacity, fillOpacity,
1740 hasStrokeParam, hasDefaultStrokeColor, strokeColor,
1741 hasStrokeWidthParam, hasDefaultStrokeWidth, strokeWidth,
1742 hasStrokeOpacityParam, hasDefaultStrokeOpacity, strokeOpacity );
1743 if ( hasDefaultFillColor )
1747 if ( hasDefaultFillOpacity )
1750 c.setAlphaF( fillOpacity );
1753 if ( hasDefaultStrokeColor )
1757 if ( hasDefaultStrokeWidth )
1761 if ( hasDefaultStrokeOpacity )
1764 c.setAlphaF( strokeOpacity );
1769 if ( props.contains( QStringLiteral(
"size_unit" ) ) )
1771 if ( props.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
1773 if ( props.contains( QStringLiteral(
"fixedAspectRatio" ) ) )
1775 if ( props.contains( QStringLiteral(
"offset" ) ) )
1777 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
1779 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
1781 if ( props.contains( QStringLiteral(
"fill" ) ) )
1786 else if ( props.contains( QStringLiteral(
"color" ) ) )
1790 if ( props.contains( QStringLiteral(
"outline" ) ) )
1795 else if ( props.contains( QStringLiteral(
"outline_color" ) ) )
1799 else if ( props.contains( QStringLiteral(
"line_color" ) ) )
1804 if ( props.contains( QStringLiteral(
"outline-width" ) ) )
1807 m->
setStrokeWidth( props[QStringLiteral(
"outline-width" )].toDouble() );
1809 else if ( props.contains( QStringLiteral(
"outline_width" ) ) )
1811 m->
setStrokeWidth( props[QStringLiteral(
"outline_width" )].toDouble() );
1813 else if ( props.contains( QStringLiteral(
"line_width" ) ) )
1815 m->
setStrokeWidth( props[QStringLiteral(
"line_width" )].toDouble() );
1818 if ( props.contains( QStringLiteral(
"outline_width_unit" ) ) )
1822 else if ( props.contains( QStringLiteral(
"line_width_unit" ) ) )
1826 if ( props.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
1829 if ( props.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
1833 if ( props.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
1847 QgsStringMap::iterator it = properties.find( QStringLiteral(
"name" ) );
1848 if ( it != properties.end() )
1860 QColor defaultFillColor, defaultStrokeColor;
1861 double strokeWidth, fillOpacity, strokeOpacity;
1862 bool hasFillParam =
false, hasFillOpacityParam =
false, hasStrokeParam =
false, hasStrokeWidthParam =
false, hasStrokeOpacityParam =
false;
1863 bool hasDefaultFillColor =
false, hasDefaultFillOpacity =
false, hasDefaultStrokeColor =
false, hasDefaultStrokeWidth =
false, hasDefaultStrokeOpacity =
false;
1865 hasFillOpacityParam, hasDefaultFillOpacity, fillOpacity,
1866 hasStrokeParam, hasDefaultStrokeColor, defaultStrokeColor,
1867 hasStrokeWidthParam, hasDefaultStrokeWidth, strokeWidth,
1868 hasStrokeOpacityParam, hasDefaultStrokeOpacity, strokeOpacity );
1870 double newFillOpacity = hasFillOpacityParam ?
fillColor().alphaF() : 1.0;
1871 double newStrokeOpacity = hasStrokeOpacityParam ?
strokeColor().alphaF() : 1.0;
1873 if ( hasDefaultFillColor )
1875 defaultFillColor.setAlphaF( newFillOpacity );
1878 if ( hasDefaultFillOpacity )
1881 c.setAlphaF( fillOpacity );
1884 if ( hasDefaultStrokeColor )
1886 defaultStrokeColor.setAlphaF( newStrokeOpacity );
1889 if ( hasDefaultStrokeWidth )
1891 setStrokeWidth( strokeWidth );
1893 if ( hasDefaultStrokeOpacity )
1896 c.setAlphaF( strokeOpacity );
1900 updateDefaultAspectRatio();
1905 if ( mDefaultAspectRatio == 0.0 )
1910 double widthScaleFactor = 3.465;
1913 mDefaultAspectRatio = svgViewbox.isValid() ? svgViewbox.height() / svgViewbox.width() : 0.0;
1915 return mDefaultAspectRatio;
1920 bool aPreservedAspectRatio = preservedAspectRatio();
1921 if ( aPreservedAspectRatio && !par )
1923 mFixedAspectRatio = mDefaultAspectRatio;
1925 else if ( !aPreservedAspectRatio && par )
1927 mFixedAspectRatio = 0.0;
1929 return preservedAspectRatio();
1935 return QStringLiteral(
"SvgMarker" );
1941 Q_UNUSED( context );
1946 Q_UNUSED( context );
1955 bool hasDataDefinedSize =
false;
1956 double scaledSize =
calculateSize( context, hasDataDefinedSize );
1960 if ( static_cast< int >( size ) < 1 || 10000.0 < size )
1967 bool hasDataDefinedAspectRatio =
false;
1968 double aspectRatio = calculateAspectRatio( context, scaledSize, hasDataDefinedAspectRatio );
1970 QPointF outputOffset;
1974 p->translate( point + outputOffset );
1980 QString path =
mPath;
1988 double strokeWidth = mStrokeWidth;
2010 bool fitsInCache =
true;
2011 bool usePict =
true;
2012 double hwRatio = 1.0;
2018 if ( fitsInCache && img.width() > 1 )
2023 QImage transparentImage = img.copy();
2025 p->drawImage( -transparentImage.width() / 2.0, -transparentImage.height() / 2.0, transparentImage );
2026 hwRatio =
static_cast< double >( transparentImage.height() ) / static_cast< double >( transparentImage.width() );
2030 p->drawImage( -img.width() / 2.0, -img.height() / 2.0, img );
2031 hwRatio =
static_cast< double >( img.height() ) / static_cast< double >( img.width() );
2036 if ( usePict || !fitsInCache )
2038 p->setOpacity( context.
opacity() );
2041 if ( pct.width() > 1 )
2044 _fixQPictureDPI( p );
2045 p->drawPicture( 0, 0, pct );
2047 hwRatio =
static_cast< double >( pct.height() ) / static_cast< double >( pct.width() );
2055 if ( penWidth > size / 20 )
2058 penWidth = size / 20;
2060 double penOffset = penWidth / 2;
2061 pen.setWidth( penWidth );
2063 p->setBrush( Qt::NoBrush );
2064 double wSize = size + penOffset;
2065 double hSize = size * hwRatio + penOffset;
2066 p->drawRect( QRectF( -wSize / 2.0, -hSize / 2.0, wSize, hSize ) );
2074 p->setRenderHint( QPainter::Antialiasing );
2079 double QgsSvgMarkerSymbolLayer::calculateSize(
QgsSymbolRenderContext &context,
bool &hasDataDefinedSize )
const 2081 double scaledSize =
mSize;
2085 if ( hasDataDefinedSize )
2093 if ( hasDataDefinedSize )
2100 if ( hasDataDefinedSize && ok )
2105 scaledSize = std::sqrt( scaledSize );
2118 if ( !hasDataDefinedAspectRatio )
2119 return mFixedAspectRatio;
2124 double scaledAspectRatio = mDefaultAspectRatio;
2125 if ( mFixedAspectRatio > 0.0 )
2126 scaledAspectRatio = mFixedAspectRatio;
2128 double defaultHeight =
mSize * scaledAspectRatio;
2129 scaledAspectRatio = defaultHeight / scaledSize;
2132 double scaledHeight = scaledSize * scaledAspectRatio;
2139 if ( hasDataDefinedAspectRatio && ok )
2144 scaledHeight = sqrt( scaledHeight );
2151 scaledAspectRatio = scaledHeight / scaledSize;
2153 return scaledAspectRatio;
2161 markerOffset( context, scaledSize, scaledSize, offsetX, offsetY );
2162 offset = QPointF( offsetX, offsetY );
2172 if ( hasDataDefinedRotation )
2198 map[QStringLiteral(
"name" )] =
mPath;
2199 map[QStringLiteral(
"size" )] = QString::number(
mSize );
2202 map[QStringLiteral(
"fixedAspectRatio" )] = QString::number( mFixedAspectRatio );
2203 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
2210 map[QStringLiteral(
"outline_width" )] = QString::number( mStrokeWidth );
2242 mStrokeWidthUnit = unit;
2248 if ( unit != mStrokeWidthUnit )
2258 mStrokeWidthMapUnitScale = scale;
2265 return mStrokeWidthMapUnitScale;
2273 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
2274 element.appendChild( graphicElem );
2284 double angle = props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toDouble( &ok );
2287 angleFunc = QStringLiteral(
"%1 + %2" ).arg( props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ) ).arg(
mAngle );
2291 angleFunc = QString::number( angle +
mAngle );
2305 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
2306 if ( graphicElem.isNull() )
2309 QString path, mimeType;
2316 QString uom = element.attribute( QStringLiteral(
"uom" ) );
2319 if ( mimeType != QLatin1String(
"image/svg+xml" ) )
2327 double d = angleFunc.toDouble( &ok );
2347 Q_UNUSED( layerName );
2356 if ( hasDataDefinedSize )
2362 if ( hasDataDefinedSize && ok )
2367 size = std::sqrt( size );
2376 size *= mmMapUnitScaleFactor;
2379 double halfSize = size / 2.0;
2391 double offsetX = offset.x();
2392 double offsetY = offset.y();
2394 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 );
2461 pd.
setShift( shift + QPointF( outputOffset.x(), -outputOffset.y() ) );
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)
Gets 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)
double symbologyScale() const
Returns the reference scale for output.
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 clipValueToMapUnitScale(double &value, const QgsMapUnitScale &scale, double pixelToMMFactor) const
Clips value to scale minimum/maximum.
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.
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)
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.
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
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)
QgsUnitTypes::RenderUnit mSizeUnit
Marker size unit.
virtual QColor strokeColor() const
Gets 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
Returns combination of flags used for rendering.
QgsUnitTypes::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
QgsUnitTypes::DistanceUnit mapUnits() const
Retrieve map units.
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)
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
Returns current map rotation in degrees.
#define DEFAULT_FONTMARKER_SIZE
QColor strokeColor() const override
Gets 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
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)
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)
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.
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
Gets 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.
double mapUnitsPerPixel() const
Returns current map units per pixel.
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)
Gets SVG content.
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer's subsymbol. takes ownership of the passed symbol.
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)
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 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.
#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
Gets 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...