44#include <QSvgRenderer>
45#include <QDomDocument>
55 Qt::PenJoinStyle penJoinStyle )
56 : mBrushStyle( style )
57 , mStrokeColor( strokeColor )
58 , mStrokeStyle( strokeStyle )
59 , mStrokeWidth( strokeWidth )
60 , mPenJoinStyle( penJoinStyle )
104void QgsSimpleFillSymbolLayer::applyDataDefinedSymbology(
QgsSymbolRenderContext &context, QBrush &brush, QPen &pen, QPen &selPen )
129 penColor.setAlphaF( context.
opacity() * penColor.alphaF() );
130 pen.setColor( penColor );
138 double width = exprVal.toDouble( &ok );
142 pen.setWidthF( width );
143 selPen.setWidthF( width );
180 if ( props.contains( QStringLiteral(
"color" ) ) )
182 if ( props.contains( QStringLiteral(
"style" ) ) )
184 if ( props.contains( QStringLiteral(
"color_border" ) ) )
189 else if ( props.contains( QStringLiteral(
"outline_color" ) ) )
193 else if ( props.contains( QStringLiteral(
"line_color" ) ) )
198 if ( props.contains( QStringLiteral(
"style_border" ) ) )
203 else if ( props.contains( QStringLiteral(
"outline_style" ) ) )
207 else if ( props.contains( QStringLiteral(
"line_style" ) ) )
211 if ( props.contains( QStringLiteral(
"width_border" ) ) )
214 strokeWidth = props[QStringLiteral(
"width_border" )].toDouble();
216 else if ( props.contains( QStringLiteral(
"outline_width" ) ) )
218 strokeWidth = props[QStringLiteral(
"outline_width" )].toDouble();
220 else if ( props.contains( QStringLiteral(
"line_width" ) ) )
222 strokeWidth = props[QStringLiteral(
"line_width" )].toDouble();
224 if ( props.contains( QStringLiteral(
"offset" ) ) )
226 if ( props.contains( QStringLiteral(
"joinstyle" ) ) )
231 if ( props.contains( QStringLiteral(
"border_width_unit" ) ) )
235 else if ( props.contains( QStringLiteral(
"outline_width_unit" ) ) )
239 else if ( props.contains( QStringLiteral(
"line_width_unit" ) ) )
243 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
246 if ( props.contains( QStringLiteral(
"border_width_map_unit_scale" ) ) )
248 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
251 sl->restoreOldDataDefinedProperties( props );
259 return QStringLiteral(
"SimpleFill" );
271 selColor.setAlphaF( context.
opacity() );
331 if (
mBrush.style() == Qt::SolidPattern ||
mBrush.style() == Qt::NoBrush || !
dynamic_cast<QPrinter *
>( p->device() ) )
345 p->setPen( Qt::NoPen );
349 p->setBrush( Qt::NoBrush );
367 map[QStringLiteral(
"outline_width" )] = QString::number(
mStrokeWidth );
395 QDomElement symbolizerElem = doc.createElement( QStringLiteral(
"se:PolygonSymbolizer" ) );
396 if ( !props.value( QStringLiteral(
"uom" ), QString() ).toString().isEmpty() )
397 symbolizerElem.setAttribute( QStringLiteral(
"uom" ), props.value( QStringLiteral(
"uom" ), QString() ).toString() );
398 element.appendChild( symbolizerElem );
407 bool exportOk {
false };
411 if ( ! image.isNull() )
414 QDomElement fillElem = doc.createElement( QStringLiteral(
"se:Fill" ) );
415 symbolizerElem.appendChild( fillElem );
416 QDomElement graphicFillElem = doc.createElement( QStringLiteral(
"se:GraphicFill" ) );
417 fillElem.appendChild( graphicFillElem );
418 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
419 graphicFillElem.appendChild( graphicElem );
421 const QFileInfo info { context.exportFilePath() };
422 QString pngPath { info.completeSuffix().isEmpty() ? context.exportFilePath() : context.exportFilePath().chopped( info.completeSuffix().length() ).append( QStringLiteral(
"png" ) ) };
424 image.save( pngPath );
439 const double alpha { props.value( QStringLiteral(
"alpha" ), QVariant() ).toDouble( &ok ) };
445 QDomElement fillElem = doc.createElement( QStringLiteral(
"se:Fill" ) );
446 symbolizerElem.appendChild( fillElem );
453 QDomElement strokeElem = doc.createElement( QStringLiteral(
"se:Stroke" ) );
454 symbolizerElem.appendChild( strokeElem );
458 const double alpha { props.value( QStringLiteral(
"alpha" ), QVariant() ).toDouble( &ok ) };
478 symbolStyle.append(
';' );
487 Qt::BrushStyle fillStyle;
491 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
494 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
500 double scaleFactor = 1.0;
501 const QString uom = element.attribute( QStringLiteral(
"uom" ) );
508 sl->setOutputUnit( sldUnitSize );
517 return penBleed + offsetBleed;
575 QPixmap pixmap( QSize( 32, 32 ) );
576 pixmap.fill( Qt::transparent );
578 painter.begin( &pixmap );
579 painter.setRenderHint( QPainter::Antialiasing );
587 std::unique_ptr< QgsSimpleFillSymbolLayer > layerClone(
clone() );
588 layerClone->setStrokeStyle( Qt::PenStyle::NoPen );
589 layerClone->drawPreviewIcon( symbolContext, pixmap.size() );
591 return pixmap.toImage();
599 : mGradientColorType( colorType )
600 , mGradientType( gradientType )
601 , mCoordinateMode( coordinateMode )
602 , mGradientSpread( spread )
603 , mReferencePoint1( QPointF( 0.5, 0 ) )
604 , mReferencePoint2( QPointF( 0.5, 1 ) )
625 bool refPoint1IsCentroid =
false;
627 bool refPoint2IsCentroid =
false;
632 if ( props.contains( QStringLiteral(
"type" ) ) )
634 if ( props.contains( QStringLiteral(
"coordinate_mode" ) ) )
636 if ( props.contains( QStringLiteral(
"spread" ) ) )
638 if ( props.contains( QStringLiteral(
"color_type" ) ) )
640 if ( props.contains( QStringLiteral(
"gradient_color" ) ) )
645 else if ( props.contains( QStringLiteral(
"color" ) ) )
649 if ( props.contains( QStringLiteral(
"gradient_color2" ) ) )
654 if ( props.contains( QStringLiteral(
"reference_point1" ) ) )
656 if ( props.contains( QStringLiteral(
"reference_point1_iscentroid" ) ) )
657 refPoint1IsCentroid = props[QStringLiteral(
"reference_point1_iscentroid" )].toInt();
658 if ( props.contains( QStringLiteral(
"reference_point2" ) ) )
660 if ( props.contains( QStringLiteral(
"reference_point2_iscentroid" ) ) )
661 refPoint2IsCentroid = props[QStringLiteral(
"reference_point2_iscentroid" )].toInt();
662 if ( props.contains( QStringLiteral(
"angle" ) ) )
663 angle = props[QStringLiteral(
"angle" )].toDouble();
665 if ( props.contains( QStringLiteral(
"offset" ) ) )
682 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
684 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
687 sl->setReferencePoint1IsCentroid( refPoint1IsCentroid );
689 sl->setReferencePoint2IsCentroid( refPoint2IsCentroid );
690 sl->setAngle(
angle );
692 sl->setColorRamp( gradientRamp );
694 sl->restoreOldDataDefinedProperties( props );
707 return QStringLiteral(
"GradientFill" );
710void QgsGradientFillSymbolLayer::applyDataDefinedSymbology(
QgsSymbolRenderContext &context,
const QPolygonF &points )
755 if ( currentType == QObject::tr(
"linear" ) )
759 else if ( currentType == QObject::tr(
"radial" ) )
763 else if ( currentType == QObject::tr(
"conical" ) )
777 if ( currentCoordMode == QObject::tr(
"feature" ) )
781 else if ( currentCoordMode == QObject::tr(
"viewport" ) )
795 if ( currentSpread == QObject::tr(
"pad" ) )
799 else if ( currentSpread == QObject::tr(
"repeat" ) )
803 else if ( currentSpread == QObject::tr(
"reflect" ) )
850 if ( refPoint1IsCentroid || refPoint2IsCentroid )
855 QRectF bbox = points.boundingRect();
856 double centroidX = ( centroid.
x() - bbox.left() ) / bbox.width();
857 double centroidY = ( centroid.
y() - bbox.top() ) / bbox.height();
859 if ( refPoint1IsCentroid )
861 refPoint1X = centroidX;
862 refPoint1Y = centroidY;
864 if ( refPoint2IsCentroid )
866 refPoint2X = centroidX;
867 refPoint2Y = centroidY;
873 spread, QPointF( refPoint1X, refPoint1Y ), QPointF( refPoint2X, refPoint2Y ),
angle );
876QPointF QgsGradientFillSymbolLayer::rotateReferencePoint( QPointF refPoint,
double angle )
881 QLineF refLine = QLineF( QPointF( 0.5, 0.5 ), refPoint );
883 refLine.setAngle( refLine.angle() +
angle );
885 QPointF rotatedReferencePoint = refLine.p2();
887 if ( rotatedReferencePoint.x() > 1 )
888 rotatedReferencePoint.setX( 1 );
889 if ( rotatedReferencePoint.x() < 0 )
890 rotatedReferencePoint.setX( 0 );
891 if ( rotatedReferencePoint.y() > 1 )
892 rotatedReferencePoint.setY( 1 );
893 if ( rotatedReferencePoint.y() < 0 )
894 rotatedReferencePoint.setY( 0 );
896 return rotatedReferencePoint;
903 QPointF referencePoint1, QPointF referencePoint2,
const double angle )
908 QColor fillColor2 =
color2;
909 fillColor2.setAlphaF( context.
opacity() * fillColor2.alphaF() );
920 gradient = QLinearGradient( rotatedReferencePoint1, rotatedReferencePoint2 );
923 gradient = QRadialGradient( rotatedReferencePoint1, QLineF( rotatedReferencePoint1, rotatedReferencePoint2 ).length() );
926 gradient = QConicalGradient( rotatedReferencePoint1, QLineF( rotatedReferencePoint1, rotatedReferencePoint2 ).
angle() );
932 gradient.setCoordinateMode( QGradient::ObjectBoundingMode );
935 gradient.setCoordinateMode( QGradient::StretchToDeviceMode );
941 gradient.setSpread( QGradient::PadSpread );
944 gradient.setSpread( QGradient::ReflectSpread );
947 gradient.setSpread( QGradient::RepeatSpread );
963 gradient.setColorAt( 1.0, fillColor2 );
967 brush = QBrush( gradient );
974 selColor.setAlphaF( context.
opacity() );
991 applyDataDefinedSymbology( context, points );
995 p->setPen( Qt::NoPen );
1028 map[QStringLiteral(
"color_type" )] = QString::number(
static_cast< int >(
mGradientColorType ) );
1029 map[QStringLiteral(
"type" )] = QString::number(
static_cast<int>(
mGradientType ) );
1030 map[QStringLiteral(
"coordinate_mode" )] = QString::number(
static_cast< int >(
mCoordinateMode ) );
1031 map[QStringLiteral(
"spread" )] = QString::number(
static_cast< int >(
mGradientSpread ) );
1036 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
1042#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
1066 return sl.release();
1108 int blurRadius,
bool useWholeShape,
double maxDistance )
1109 : mBlurRadius( blurRadius )
1110 , mUseWholeShape( useWholeShape )
1111 , mMaxDistance( maxDistance )
1112 , mColorType( colorType )
1131 if ( props.contains( QStringLiteral(
"color_type" ) ) )
1135 if ( props.contains( QStringLiteral(
"shapeburst_color" ) ) )
1140 else if ( props.contains( QStringLiteral(
"color" ) ) )
1145 if ( props.contains( QStringLiteral(
"shapeburst_color2" ) ) )
1150 else if ( props.contains( QStringLiteral(
"gradient_color2" ) ) )
1154 if ( props.contains( QStringLiteral(
"blur_radius" ) ) )
1156 blurRadius = props[QStringLiteral(
"blur_radius" )].toInt();
1158 if ( props.contains( QStringLiteral(
"use_whole_shape" ) ) )
1160 useWholeShape = props[QStringLiteral(
"use_whole_shape" )].toInt();
1162 if ( props.contains( QStringLiteral(
"max_distance" ) ) )
1164 maxDistance = props[QStringLiteral(
"max_distance" )].toDouble();
1166 if ( props.contains( QStringLiteral(
"offset" ) ) )
1185 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
1189 if ( props.contains( QStringLiteral(
"distance_unit" ) ) )
1193 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
1197 if ( props.contains( QStringLiteral(
"distance_map_unit_scale" ) ) )
1201 if ( props.contains( QStringLiteral(
"ignore_rings" ) ) )
1203 sl->setIgnoreRings( props[QStringLiteral(
"ignore_rings" )].toInt() );
1207 sl->setColorRamp( gradientRamp );
1210 sl->restoreOldDataDefinedProperties( props );
1212 return sl.release();
1217 return QStringLiteral(
"ShapeburstFill" );
1222 if ( mGradientRamp.get() == ramp )
1225 mGradientRamp.reset( ramp );
1228void QgsShapeburstFillSymbolLayer::applyDataDefinedSymbology(
QgsSymbolRenderContext &context, QColor &color, QColor &color2,
int &blurRadius,
bool &useWholeShape,
1229 double &maxDistance,
bool &ignoreRings )
1286 selColor.setAlphaF( context.
opacity() );
1287 mSelBrush = QBrush( selColor );
1304 if ( useSelectedColor )
1307 p->setBrush( mSelBrush );
1308 QPointF
offset = mOffset;
1343 int outputPixelMaxDist = 0;
1351 std::unique_ptr< QgsGradientColorRamp > twoColorGradientRamp;
1354 twoColorGradientRamp = std::make_unique< QgsGradientColorRamp >( color1,
color2 );
1358 p->setPen( QPen( Qt::NoPen ) );
1363 int pointsWidth =
static_cast< int >( std::round( points.boundingRect().width() ) );
1364 int pointsHeight =
static_cast< int >( std::round( points.boundingRect().height() ) );
1365 int imWidth = pointsWidth + ( sideBuffer * 2 );
1366 int imHeight = pointsHeight + ( sideBuffer * 2 );
1372 std::unique_ptr< QImage > fillImage = std::make_unique< QImage >( imWidth,
1373 imHeight, QImage::Format_ARGB32_Premultiplied );
1374 if ( fillImage->isNull() )
1384 std::unique_ptr< QImage > alphaImage = std::make_unique< QImage >( fillImage->width(), fillImage->height(), QImage::Format_ARGB32_Premultiplied );
1385 if ( alphaImage->isNull() )
1397 fillImage->fill( Qt::black );
1403 alphaImage->fill( Qt::transparent );
1409 QPainter imgPainter;
1410 imgPainter.begin( alphaImage.get() );
1411 imgPainter.setRenderHint( QPainter::Antialiasing,
true );
1412 imgPainter.setBrush( QBrush( Qt::white ) );
1413 imgPainter.setPen( QPen( Qt::black ) );
1414 imgPainter.translate( -points.boundingRect().left() + sideBuffer, - points.boundingRect().top() + sideBuffer );
1423 imgPainter.begin( fillImage.get() );
1426 imgPainter.drawImage( 0, 0, *alphaImage );
1433 imgPainter.setBrush( QBrush( Qt::white ) );
1434 imgPainter.setPen( QPen( Qt::black ) );
1435 imgPainter.translate( -points.boundingRect().left() + sideBuffer, - points.boundingRect().top() + sideBuffer );
1444 double *dtArray = distanceTransform( fillImage.get(), context.
renderContext() );
1464 imgPainter.begin( fillImage.get() );
1465 imgPainter.setCompositionMode( QPainter::CompositionMode_DestinationIn );
1466 imgPainter.drawImage( 0, 0, *alphaImage );
1474 QPointF
offset = mOffset;
1491 p->drawImage( points.boundingRect().left() - sideBuffer, points.boundingRect().top() - sideBuffer, *fillImage );
1502void QgsShapeburstFillSymbolLayer::distanceTransform1d(
double *f,
int n,
int *v,
double *z,
double *d )
1508 for (
int q = 1; q <= n - 1; q++ )
1510 double s = ( ( f[q] +
static_cast< double >( q ) * q ) - ( f[v[k]] + (
static_cast< double >( v[k] ) * v[k] ) ) ) / ( 2 * q - 2 * v[k] );
1514 s = ( ( f[q] +
static_cast< double >( q ) * q ) - ( f[v[k]] + (
static_cast< double >( v[k] ) * v[k] ) ) ) / ( 2 * q - 2 * v[k] );
1523 for (
int q = 0; q <= n - 1; q++ )
1525 while ( z[k + 1] < q )
1527 d[q] =
static_cast< double >( q - v[k] ) * ( q - v[k] ) + f[v[k]];
1532void QgsShapeburstFillSymbolLayer::distanceTransform2d(
double *im,
int width,
int height,
QgsRenderContext &context )
1534 int maxDimension = std::max( width, height );
1535 double *f =
new double[ maxDimension ];
1536 int *v =
new int[ maxDimension ];
1537 double *z =
new double[ maxDimension + 1 ];
1538 double *d =
new double[ maxDimension ];
1541 for (
int x = 0; x < width; x++ )
1546 for (
int y = 0; y < height; y++ )
1548 f[y] = im[ x +
static_cast< std::size_t
>( y ) * width ];
1550 distanceTransform1d( f, height, v, z, d );
1551 for (
int y = 0; y < height; y++ )
1553 im[ x +
static_cast< std::size_t
>( y ) * width ] = d[y];
1558 for (
int y = 0; y < height; y++ )
1563 for (
int x = 0; x < width; x++ )
1565 f[x] = im[ x +
static_cast< std::size_t
>( y ) * width ];
1567 distanceTransform1d( f, width, v, z, d );
1568 for (
int x = 0; x < width; x++ )
1570 im[ x +
static_cast< std::size_t
>( y ) * width ] = d[x];
1581double *QgsShapeburstFillSymbolLayer::distanceTransform( QImage *im,
QgsRenderContext &context )
1583 int width = im->width();
1584 int height = im->height();
1586 double *dtArray =
new double[
static_cast< std::size_t
>( width ) * height];
1590 std::size_t idx = 0;
1591 for (
int heightIndex = 0; heightIndex < height; ++heightIndex )
1596 const QRgb *scanLine =
reinterpret_cast< const QRgb *
>( im->constScanLine( heightIndex ) );
1597 for (
int widthIndex = 0; widthIndex < width; ++widthIndex )
1599 tmpRgb = scanLine[widthIndex];
1600 if ( qRed( tmpRgb ) == 0 )
1608 dtArray[ idx ] =
INF;
1615 distanceTransform2d( dtArray, width, height, context );
1620void QgsShapeburstFillSymbolLayer::dtArrayToQImage(
double *array, QImage *im,
QgsColorRamp *ramp,
QgsRenderContext &context,
bool useWholeShape,
int maxPixelDistance )
1622 int width = im->width();
1623 int height = im->height();
1626 double maxDistanceValue;
1631 double dtMaxValue = array[0];
1632 for ( std::size_t i = 1; i < static_cast< std::size_t >( width ) * height; ++i )
1634 if ( array[i] > dtMaxValue )
1636 dtMaxValue = array[i];
1641 maxDistanceValue = std::sqrt( dtMaxValue );
1646 maxDistanceValue = maxPixelDistance;
1650 std::size_t idx = 0;
1651 double squaredVal = 0;
1654 for (
int heightIndex = 0; heightIndex < height; ++heightIndex )
1659 QRgb *scanLine =
reinterpret_cast< QRgb *
>( im->scanLine( heightIndex ) );
1660 for (
int widthIndex = 0; widthIndex < width; ++widthIndex )
1663 squaredVal = array[idx];
1666 if ( maxDistanceValue > 0 )
1668 pixVal = squaredVal > 0 ? std::min( ( std::sqrt( squaredVal ) / maxDistanceValue ), 1.0 ) : 0;
1677 scanLine[widthIndex] = qPremultiply( ramp->
color( pixVal ).rgba() );
1688 map[QStringLiteral(
"color_type" )] = QString::number(
static_cast< int >( mColorType ) );
1689 map[QStringLiteral(
"blur_radius" )] = QString::number( mBlurRadius );
1690 map[QStringLiteral(
"use_whole_shape" )] = QString::number( mUseWholeShape );
1691 map[QStringLiteral(
"max_distance" )] = QString::number( mMaxDistance );
1694 map[QStringLiteral(
"ignore_rings" )] = QString::number( mIgnoreRings );
1698 if ( mGradientRamp )
1700#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
1701 map.unite( mGradientRamp->properties() );
1703 map.insert( mGradientRamp->properties() );
1712 std::unique_ptr< QgsShapeburstFillSymbolLayer > sl = std::make_unique< QgsShapeburstFillSymbolLayer >(
mColor, mColor2, mColorType, mBlurRadius, mUseWholeShape, mMaxDistance );
1713 if ( mGradientRamp )
1715 sl->setColorRamp( mGradientRamp->clone() );
1717 sl->setDistanceUnit( mDistanceUnit );
1718 sl->setDistanceMapUnitScale( mDistanceMapUnitScale );
1719 sl->setIgnoreRings( mIgnoreRings );
1720 sl->setOffset( mOffset );
1721 sl->setOffsetUnit( mOffsetUnit );
1722 sl->setOffsetMapUnitScale( mOffsetMapUnitScale );
1725 return sl.release();
1730 double offsetBleed = context.
convertToPainterUnits( std::max( std::fabs( mOffset.x() ), std::fabs( mOffset.y() ) ), mOffsetUnit, mOffsetMapUnitScale );
1741 mDistanceUnit = unit;
1747 if ( mDistanceUnit == mOffsetUnit )
1749 return mDistanceUnit;
1762 mDistanceMapUnitScale = scale;
1763 mOffsetMapUnitScale = scale;
1768 if ( mDistanceMapUnitScale == mOffsetMapUnitScale )
1770 return mDistanceMapUnitScale;
1795 p->setPen( QPen( Qt::NoPen ) );
1797 QTransform bkTransform =
mBrush.transform();
1801 QTransform t =
mBrush.transform();
1802 t.translate( leftCorner.x(), leftCorner.y() );
1803 mBrush.setTransform( t );
1807 QTransform t =
mBrush.transform();
1808 t.translate( 0, 0 );
1809 mBrush.setTransform( t );
1813 if ( useSelectedColor )
1816 p->setBrush( QBrush( selColor ) );
1822 QTransform t =
mBrush.transform();
1824 mBrush.setTransform( t );
1829 mBrush.setTransform( bkTransform );
1865 return Qt::SolidLine;
1869 return Qt::SolidLine;
1873 return mStroke->dxfPenStyle();
1909 , mPatternWidth( width )
1913 mColor = QColor( 255, 255, 255 );
1919 , mPatternWidth( width )
1920 , mSvgData( svgData )
1925 mColor = QColor( 255, 255, 255 );
1926 setDefaultSvgParams();
1934 mPatternWidthUnit = unit;
1935 mSvgStrokeWidthUnit = unit;
1938 mStroke->setOutputUnit( unit );
1944 if ( mPatternWidthUnit != unit || mSvgStrokeWidthUnit != unit ||
mStrokeWidthUnit != unit )
1954 mPatternWidthMapUnitScale = scale;
1955 mSvgStrokeWidthMapUnitScale = scale;
1961 mPatternWidthMapUnitScale == mSvgStrokeWidthMapUnitScale &&
1964 return mPatternWidthMapUnitScale;
1974 mSvgFilePath = svgPath;
1975 setDefaultSvgParams();
1985 if (
properties.contains( QStringLiteral(
"width" ) ) )
1987 width =
properties[QStringLiteral(
"width" )].toDouble();
1989 if (
properties.contains( QStringLiteral(
"svgFile" ) ) )
1993 if (
properties.contains( QStringLiteral(
"angle" ) ) )
1998 std::unique_ptr< QgsSVGFillSymbolLayer > symbolLayer;
2001 symbolLayer = std::make_unique< QgsSVGFillSymbolLayer >(
svgFilePath, width,
angle );
2005 if (
properties.contains( QStringLiteral(
"data" ) ) )
2007 data = QByteArray::fromHex(
properties[QStringLiteral(
"data" )].toString().toLocal8Bit() );
2009 symbolLayer = std::make_unique< QgsSVGFillSymbolLayer >( data, width,
angle );
2013 if (
properties.contains( QStringLiteral(
"svgFillColor" ) ) )
2018 else if (
properties.contains( QStringLiteral(
"color" ) ) )
2022 if (
properties.contains( QStringLiteral(
"svgOutlineColor" ) ) )
2027 else if (
properties.contains( QStringLiteral(
"outline_color" ) ) )
2031 else if (
properties.contains( QStringLiteral(
"line_color" ) ) )
2035 if (
properties.contains( QStringLiteral(
"svgOutlineWidth" ) ) )
2038 symbolLayer->setSvgStrokeWidth(
properties[QStringLiteral(
"svgOutlineWidth" )].toDouble() );
2040 else if (
properties.contains( QStringLiteral(
"outline_width" ) ) )
2042 symbolLayer->setSvgStrokeWidth(
properties[QStringLiteral(
"outline_width" )].toDouble() );
2044 else if (
properties.contains( QStringLiteral(
"line_width" ) ) )
2046 symbolLayer->setSvgStrokeWidth(
properties[QStringLiteral(
"line_width" )].toDouble() );
2050 if (
properties.contains( QStringLiteral(
"pattern_width_unit" ) ) )
2054 if (
properties.contains( QStringLiteral(
"pattern_width_map_unit_scale" ) ) )
2058 if (
properties.contains( QStringLiteral(
"svg_outline_width_unit" ) ) )
2062 if (
properties.contains( QStringLiteral(
"svg_outline_width_map_unit_scale" ) ) )
2066 if (
properties.contains( QStringLiteral(
"outline_width_unit" ) ) )
2070 if (
properties.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
2075 if (
properties.contains( QStringLiteral(
"parameters" ) ) )
2081 symbolLayer->restoreOldDataDefinedProperties(
properties );
2083 return symbolLayer.release();
2088 QVariantMap::iterator it =
properties.find( QStringLiteral(
"svgFile" ) );
2100 return QStringLiteral(
"SVGFill" );
2103void QgsSVGFillSymbolLayer::applyPattern( QBrush &brush,
const QString &svgFilePath,
double patternWidth,
Qgis::RenderUnit patternWidthUnit,
2104 const QColor &svgFillColor,
const QColor &svgStrokeColor,
double svgStrokeWidth,
2108 if ( mSvgViewBox.isNull() )
2115 if (
static_cast< int >( size ) < 1.0 || 10000.0 < size )
2117 brush.setTextureImage( QImage() );
2121 bool fitsInCache =
true;
2129 double hwRatio = 1.0;
2130 if ( patternPict.width() > 0 )
2132 hwRatio =
static_cast< double >( patternPict.height() ) /
static_cast< double >( patternPict.width() );
2134 patternImage = QImage(
static_cast< int >( size ),
static_cast< int >( size * hwRatio ), QImage::Format_ARGB32_Premultiplied );
2135 patternImage.fill( 0 );
2137 QPainter p( &patternImage );
2138 p.drawPicture( QPointF( size / 2, size * hwRatio / 2 ), patternPict );
2141 QTransform brushTransform;
2144 QImage transparentImage = patternImage.copy();
2146 brush.setTextureImage( transparentImage );
2150 brush.setTextureImage( patternImage );
2152 brush.setTransform( brushTransform );
2160 applyPattern(
mBrush, mSvgFilePath, mPatternWidth, mPatternWidthUnit,
mColor, mSvgStrokeColor, mSvgStrokeWidth, mSvgStrokeWidthUnit, context, mPatternWidthMapUnitScale, mSvgStrokeWidthMapUnitScale, evaluatedParameters );
2183 mStroke->renderPolyline( points, context.
feature(), context.
renderContext(), -1, useSelectedColor );
2186 for (
auto ringIt = rings->constBegin(); ringIt != rings->constEnd(); ++ringIt )
2188 mStroke->renderPolyline( *ringIt, context.
feature(), context.
renderContext(), -1, useSelectedColor );
2197 if ( !mSvgFilePath.isEmpty() )
2199 map.insert( QStringLiteral(
"svgFile" ), mSvgFilePath );
2203 map.insert( QStringLiteral(
"data" ), QString( mSvgData.toHex() ) );
2206 map.insert( QStringLiteral(
"width" ), QString::number( mPatternWidth ) );
2207 map.insert( QStringLiteral(
"angle" ), QString::number(
mAngle ) );
2212 map.insert( QStringLiteral(
"outline_width" ), QString::number( mSvgStrokeWidth ) );
2229 std::unique_ptr< QgsSVGFillSymbolLayer > clonedLayer;
2230 if ( !mSvgFilePath.isEmpty() )
2232 clonedLayer = std::make_unique< QgsSVGFillSymbolLayer >( mSvgFilePath, mPatternWidth,
mAngle );
2233 clonedLayer->setSvgFillColor(
mColor );
2234 clonedLayer->setSvgStrokeColor( mSvgStrokeColor );
2235 clonedLayer->setSvgStrokeWidth( mSvgStrokeWidth );
2239 clonedLayer = std::make_unique< QgsSVGFillSymbolLayer >( mSvgData, mPatternWidth,
mAngle );
2242 clonedLayer->setPatternWidthUnit( mPatternWidthUnit );
2243 clonedLayer->setPatternWidthMapUnitScale( mPatternWidthMapUnitScale );
2244 clonedLayer->setSvgStrokeWidthUnit( mSvgStrokeWidthUnit );
2245 clonedLayer->setSvgStrokeWidthMapUnitScale( mSvgStrokeWidthMapUnitScale );
2249 clonedLayer->setParameters( mParameters );
2253 clonedLayer->setSubSymbol( mStroke->clone() );
2257 return clonedLayer.release();
2262 QDomElement symbolizerElem = doc.createElement( QStringLiteral(
"se:PolygonSymbolizer" ) );
2263 if ( !props.value( QStringLiteral(
"uom" ), QString() ).toString().isEmpty() )
2264 symbolizerElem.setAttribute( QStringLiteral(
"uom" ), props.value( QStringLiteral(
"uom" ), QString() ).toString() );
2265 element.appendChild( symbolizerElem );
2269 QDomElement fillElem = doc.createElement( QStringLiteral(
"se:Fill" ) );
2270 symbolizerElem.appendChild( fillElem );
2272 QDomElement graphicFillElem = doc.createElement( QStringLiteral(
"se:GraphicFill" ) );
2273 fillElem.appendChild( graphicFillElem );
2275 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
2276 graphicFillElem.appendChild( graphicElem );
2278 if ( !mSvgFilePath.isEmpty() )
2289 symbolizerElem.appendChild( doc.createComment( QStringLiteral(
"SVG from data not implemented yet" ) ) );
2295 double angle = props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toDouble( &ok );
2298 angleFunc = QStringLiteral(
"%1 + %2" ).arg( props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toString() ).arg(
mAngle );
2311 mStroke->toSld( doc, element, props );
2323 return mStroke.get();
2330 mStroke.reset(
nullptr );
2343 mStroke.reset( lineSymbol );
2353 if ( mStroke && mStroke->symbolLayer( 0 ) )
2355 double subLayerBleed = mStroke->symbolLayer( 0 )->estimateMaxBleed( context );
2356 return subLayerBleed;
2366 return QColor( Qt::black );
2368 return mStroke->color();
2375 attr.unite( mStroke->usedAttributes( context ) );
2383 if ( mStroke && mStroke->hasDataDefinedProperties() )
2390 QString path, mimeType;
2392 Qt::PenStyle penStyle;
2393 double size, strokeWidth;
2395 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
2396 if ( fillElem.isNull() )
2399 QDomElement graphicFillElem = fillElem.firstChildElement( QStringLiteral(
"GraphicFill" ) );
2400 if ( graphicFillElem.isNull() )
2403 QDomElement graphicElem = graphicFillElem.firstChildElement( QStringLiteral(
"Graphic" ) );
2404 if ( graphicElem.isNull() )
2410 if ( mimeType != QLatin1String(
"image/svg+xml" ) )
2415 double scaleFactor = 1.0;
2416 const QString uom = element.attribute( QStringLiteral(
"uom" ) );
2418 size = size * scaleFactor;
2419 strokeWidth = strokeWidth * scaleFactor;
2426 double d = angleFunc.toDouble( &ok );
2431 std::unique_ptr< QgsSVGFillSymbolLayer > sl = std::make_unique< QgsSVGFillSymbolLayer >( path, size,
angle );
2432 sl->setOutputUnit( sldUnitSize );
2435 sl->setSvgStrokeWidth( strokeWidth );
2438 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
2439 if ( !strokeElem.isNull() )
2450 return sl.release();
2468 double width = mPatternWidth;
2474 QString svgFile = mSvgFilePath;
2493 double strokeWidth = mSvgStrokeWidth;
2502 mSvgStrokeWidthUnit, context, mPatternWidthMapUnitScale, mSvgStrokeWidthMapUnitScale, evaluatedParameters );
2506void QgsSVGFillSymbolLayer::storeViewBox()
2508 if ( !mSvgData.isEmpty() )
2510 QSvgRenderer r( mSvgData );
2513 mSvgViewBox = r.viewBoxF();
2518 mSvgViewBox = QRectF();
2521void QgsSVGFillSymbolLayer::setDefaultSvgParams()
2523 if ( mSvgFilePath.isEmpty() )
2528 bool hasFillParam, hasFillOpacityParam, hasStrokeParam, hasStrokeWidthParam, hasStrokeOpacityParam;
2529 bool hasDefaultFillColor, hasDefaultFillOpacity, hasDefaultStrokeColor, hasDefaultStrokeWidth, hasDefaultStrokeOpacity;
2530 QColor defaultFillColor, defaultStrokeColor;
2531 double defaultStrokeWidth, defaultFillOpacity, defaultStrokeOpacity;
2533 hasFillOpacityParam, hasDefaultFillOpacity, defaultFillOpacity,
2534 hasStrokeParam, hasDefaultStrokeColor, defaultStrokeColor,
2535 hasStrokeWidthParam, hasDefaultStrokeWidth, defaultStrokeWidth,
2536 hasStrokeOpacityParam, hasDefaultStrokeOpacity, defaultStrokeOpacity );
2538 double newFillOpacity = hasFillOpacityParam ?
mColor.alphaF() : 1.0;
2539 double newStrokeOpacity = hasStrokeOpacityParam ? mSvgStrokeColor.alphaF() : 1.0;
2541 if ( hasDefaultFillColor )
2543 mColor = defaultFillColor;
2544 mColor.setAlphaF( newFillOpacity );
2546 if ( hasDefaultFillOpacity )
2548 mColor.setAlphaF( defaultFillOpacity );
2550 if ( hasDefaultStrokeColor )
2552 mSvgStrokeColor = defaultStrokeColor;
2553 mSvgStrokeColor.setAlphaF( newStrokeOpacity );
2555 if ( hasDefaultStrokeOpacity )
2557 mSvgStrokeColor.setAlphaF( defaultStrokeOpacity );
2559 if ( hasDefaultStrokeWidth )
2561 mSvgStrokeWidth = defaultStrokeWidth;
2574 mFillLineSymbol = std::make_unique<QgsLineSymbol>( );
2582 mFillLineSymbol->setWidth( w );
2588 mFillLineSymbol->setColor(
c );
2594 return mFillLineSymbol ? mFillLineSymbol->color() :
mColor;
2606 mFillLineSymbol.reset( qgis::down_cast<QgsLineSymbol *>( symbol ) );
2615 return mFillLineSymbol.get();
2621 if ( mFillLineSymbol )
2622 attr.unite( mFillLineSymbol->usedAttributes( context ) );
2630 if ( mFillLineSymbol && mFillLineSymbol->hasDataDefinedProperties() )
2652 double lineAngleRads { qDegreesToRadians( mLineAngle ) };
2655 QSize size {
static_cast<int>( distancePx ),
static_cast<int>( distancePx ) };
2657 if (
static_cast<int>( mLineAngle ) % 90 != 0 )
2659 size = QSize(
static_cast<int>( distancePx / std::sin( lineAngleRads ) ),
static_cast<int>( distancePx / std::cos( lineAngleRads ) ) );
2662 QPixmap pixmap( size );
2663 pixmap.fill( Qt::transparent );
2665 painter.begin( &pixmap );
2666 painter.setRenderHint( QPainter::Antialiasing );
2674 std::unique_ptr< QgsLinePatternFillSymbolLayer > layerClone(
clone() );
2675 layerClone->setOffset( 0 );
2676 layerClone->drawPreviewIcon( symbolContext, pixmap.size() );
2678 return pixmap.toImage();
2690 mDistanceUnit = unit;
2691 mLineWidthUnit = unit;
2694 if ( mFillLineSymbol )
2695 mFillLineSymbol->setOutputUnit( unit );
2718 mDistanceMapUnitScale = scale;
2719 mLineWidthMapUnitScale = scale;
2720 mOffsetMapUnitScale = scale;
2726 mDistanceMapUnitScale == mLineWidthMapUnitScale &&
2727 mLineWidthMapUnitScale == mOffsetMapUnitScale )
2729 return mDistanceMapUnitScale;
2736 std::unique_ptr< QgsLinePatternFillSymbolLayer > patternLayer = std::make_unique< QgsLinePatternFillSymbolLayer >();
2742 QColor
color( Qt::black );
2745 if (
properties.contains( QStringLiteral(
"lineangle" ) ) )
2750 else if (
properties.contains( QStringLiteral(
"angle" ) ) )
2754 patternLayer->setLineAngle(
lineAngle );
2756 if (
properties.contains( QStringLiteral(
"distance" ) ) )
2760 patternLayer->setDistance(
distance );
2762 if (
properties.contains( QStringLiteral(
"linewidth" ) ) )
2767 else if (
properties.contains( QStringLiteral(
"outline_width" ) ) )
2771 else if (
properties.contains( QStringLiteral(
"line_width" ) ) )
2775 patternLayer->setLineWidth(
lineWidth );
2777 if (
properties.contains( QStringLiteral(
"color" ) ) )
2781 else if (
properties.contains( QStringLiteral(
"outline_color" ) ) )
2785 else if (
properties.contains( QStringLiteral(
"line_color" ) ) )
2789 patternLayer->setColor(
color );
2791 if (
properties.contains( QStringLiteral(
"offset" ) ) )
2795 patternLayer->setOffset(
offset );
2798 if (
properties.contains( QStringLiteral(
"distance_unit" ) ) )
2802 if (
properties.contains( QStringLiteral(
"distance_map_unit_scale" ) ) )
2806 if (
properties.contains( QStringLiteral(
"line_width_unit" ) ) )
2810 else if (
properties.contains( QStringLiteral(
"outline_width_unit" ) ) )
2814 if (
properties.contains( QStringLiteral(
"line_width_map_unit_scale" ) ) )
2818 if (
properties.contains( QStringLiteral(
"offset_unit" ) ) )
2822 if (
properties.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
2826 if (
properties.contains( QStringLiteral(
"outline_width_unit" ) ) )
2830 if (
properties.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
2834 if (
properties.contains( QStringLiteral(
"coordinate_reference" ) ) )
2838 if (
properties.contains( QStringLiteral(
"clip_mode" ) ) )
2843 patternLayer->restoreOldDataDefinedProperties(
properties );
2845 return patternLayer.release();
2850 return QStringLiteral(
"LinePatternFill" );
2853bool QgsLinePatternFillSymbolLayer::applyPattern(
const QgsSymbolRenderContext &context, QBrush &brush,
double lineAngle,
double distance )
2855 mBrush.setTextureImage( QImage() );
2857 if ( !mFillLineSymbol )
2862 std::unique_ptr< QgsLineSymbol > fillLineSymbol( mFillLineSymbol->clone() );
2863 if ( !fillLineSymbol )
2879 outputPixelOffset = std::fmod( outputPixelOffset, outputPixelDist );
2880 if ( outputPixelOffset > outputPixelDist / 2.0 )
2881 outputPixelOffset -= outputPixelDist;
2885 double outputPixelBleed = 0;
2886 double outputPixelInterval = 0;
2887 for (
int i = 0; i < fillLineSymbol->symbolLayerCount(); i++ )
2891 outputPixelBleed = std::max( outputPixelBleed, outputPixelLayerBleed );
2894 if ( markerLineLayer )
2903 outputPixelInterval = std::max( outputPixelInterval, outputPixelLayerInterval );
2907 if ( outputPixelInterval > 0 )
2911 double intervalScale = std::round( outputPixelInterval ) / outputPixelInterval;
2912 outputPixelInterval = std::round( outputPixelInterval );
2914 for (
int i = 0; i < fillLineSymbol->symbolLayerCount(); i++ )
2919 if ( markerLineLayer )
2933 height = outputPixelDist;
2934 width = outputPixelInterval > 0 ? outputPixelInterval : height;
2938 width = outputPixelDist;
2939 height = outputPixelInterval > 0 ? outputPixelInterval : width;
2943 height = outputPixelDist / std::cos(
lineAngle * M_PI / 180 );
2944 width = outputPixelDist / std::sin(
lineAngle * M_PI / 180 );
2947 lineAngle = 180 * std::atan2(
static_cast< double >( height ),
static_cast< double >( width ) ) / M_PI;
2953 height = std::abs( height );
2954 width = std::abs( width );
2956 outputPixelDist = std::abs( height * std::cos(
lineAngle * M_PI / 180 ) );
2960 int offsetHeight =
static_cast< int >( std::round( outputPixelOffset / std::cos(
lineAngle * M_PI / 180 ) ) );
2961 outputPixelOffset = offsetHeight * std::cos(
lineAngle * M_PI / 180 );
2970 int bufferMulti =
static_cast< int >( std::max( std::ceil( outputPixelBleed / width ), std::ceil( outputPixelBleed / width ) ) );
2974 bufferMulti = std::max( bufferMulti, 1 );
2976 int xBuffer = width * bufferMulti;
2977 int yBuffer = height * bufferMulti;
2978 int innerWidth = width;
2979 int innerHeight = height;
2980 width += 2 * xBuffer;
2981 height += 2 * yBuffer;
2984 if ( width > 2000 || height > 2000 || width == 0 || height == 0 )
2989 QImage patternImage( width, height, QImage::Format_ARGB32 );
2990 patternImage.fill( 0 );
2992 QPointF p1, p2, p3, p4, p5, p6;
2995 p1 = QPointF( 0, yBuffer );
2996 p2 = QPointF( width, yBuffer );
2997 p3 = QPointF( 0, yBuffer + innerHeight );
2998 p4 = QPointF( width, yBuffer + innerHeight );
3002 p1 = QPointF( xBuffer, height );
3003 p2 = QPointF( xBuffer, 0 );
3004 p3 = QPointF( xBuffer + innerWidth, height );
3005 p4 = QPointF( xBuffer + innerWidth, 0 );
3009 dx = outputPixelDist * std::cos( ( 90 -
lineAngle ) * M_PI / 180.0 );
3010 dy = outputPixelDist * std::sin( ( 90 -
lineAngle ) * M_PI / 180.0 );
3011 p1 = QPointF( 0, height );
3012 p2 = QPointF( width, 0 );
3013 p3 = QPointF( -dx, height - dy );
3014 p4 = QPointF( width - dx, -dy );
3015 p5 = QPointF( dx, height + dy );
3016 p6 = QPointF( width + dx, dy );
3020 dx = outputPixelDist * std::cos( ( 90 -
lineAngle ) * M_PI / 180.0 );
3021 dy = outputPixelDist * std::sin( ( 90 -
lineAngle ) * M_PI / 180.0 );
3022 p1 = QPointF( width, 0 );
3023 p2 = QPointF( 0, height );
3024 p3 = QPointF( width - dx, -dy );
3025 p4 = QPointF( -dx, height - dy );
3026 p5 = QPointF( width + dx, dy );
3027 p6 = QPointF( dx, height + dy );
3031 dy = outputPixelDist * std::cos( ( 180 -
lineAngle ) * M_PI / 180 );
3032 dx = outputPixelDist * std::sin( ( 180 -
lineAngle ) * M_PI / 180 );
3033 p1 = QPointF( 0, 0 );
3034 p2 = QPointF( width, height );
3035 p5 = QPointF( dx, -dy );
3036 p6 = QPointF( width + dx, height - dy );
3037 p3 = QPointF( -dx, dy );
3038 p4 = QPointF( width - dx, height + dy );
3042 dy = outputPixelDist * std::cos( ( 180 -
lineAngle ) * M_PI / 180 );
3043 dx = outputPixelDist * std::sin( ( 180 -
lineAngle ) * M_PI / 180 );
3044 p1 = QPointF( width, height );
3045 p2 = QPointF( 0, 0 );
3046 p5 = QPointF( width + dx, height - dy );
3047 p6 = QPointF( dx, -dy );
3048 p3 = QPointF( width - dx, height + dy );
3049 p4 = QPointF( -dx, dy );
3056 p3 = QPointF( tempPt.x(), tempPt.y() );
3058 p4 = QPointF( tempPt.x(), tempPt.y() );
3060 p5 = QPointF( tempPt.x(), tempPt.y() );
3062 p6 = QPointF( tempPt.x(), tempPt.y() );
3066 p1 = QPointF( tempPt.x(), tempPt.y() );
3068 p2 = QPointF( tempPt.x(), tempPt.y() );
3071 QPainter p( &patternImage );
3075 p.setRenderHint( QPainter::Antialiasing,
false );
3076 QPen pen( QColor( Qt::black ) );
3077 pen.setWidthF( 0.1 );
3078 pen.setCapStyle( Qt::FlatCap );
3083 QPolygon polygon = QPolygon() << QPoint( 0, 0 ) << QPoint( width - 1, 0 ) << QPoint( width - 1, height - 1 ) << QPoint( 0, height - 1 ) << QPoint( 0, 0 );
3084 p.drawPolygon( polygon );
3086 polygon = QPolygon() << QPoint( xBuffer, yBuffer ) << QPoint( width - xBuffer - 1, yBuffer ) << QPoint( width - xBuffer - 1, height - yBuffer - 1 ) << QPoint( xBuffer, height - yBuffer - 1 ) << QPoint( xBuffer, yBuffer );
3087 p.drawPolygon( polygon );
3093 p.setRenderHint( QPainter::Antialiasing,
true );
3106 fillLineSymbol->startRender( lineRenderContext, context.
fields() );
3108 QVector<QPolygonF> polygons;
3109 polygons.append( QPolygonF() << p1 << p2 );
3110 polygons.append( QPolygonF() << p3 << p4 );
3113 polygons.append( QPolygonF() << p5 << p6 );
3117 for (
const QPolygonF &polygon : std::as_const( polygons ) )
3119 fillLineSymbol->renderPolyline( polygon, context.
feature(), lineRenderContext, -1, useSelectedColor );
3122 fillLineSymbol->stopRender( lineRenderContext );
3126 patternImage = patternImage.copy( xBuffer, yBuffer, patternImage.width() - 2 * xBuffer, patternImage.height() - 2 * yBuffer );
3131 QImage transparentImage = patternImage.copy();
3133 brush.setTextureImage( transparentImage );
3137 brush.setTextureImage( patternImage );
3140 QTransform brushTransform;
3141 brush.setTransform( brushTransform );
3151 || mFillLineSymbol->hasDataDefinedProperties()
3155 if ( !mRenderUsingLines )
3159 mRenderUsingLines = !applyPattern( context,
mBrush, mLineAngle, mDistance );
3162 if ( mRenderUsingLines )
3164 if ( mFillLineSymbol )
3171 if ( mRenderUsingLines && mFillLineSymbol )
3179 if ( !mRenderUsingLines )
3213 outputPixelOffset = std::fmod( outputPixelOffset, outputPixelDistance );
3214 if ( outputPixelOffset > outputPixelDistance / 2.0 )
3215 outputPixelOffset -= outputPixelDistance;
3217 p->setPen( QPen( Qt::NoPen ) );
3220 if ( useSelectedColor )
3223 p->setBrush( QBrush( selColor ) );
3247 std::unique_ptr< QgsPolygon > shapePolygon;
3248 std::unique_ptr< QgsGeometryEngine > shapeEngine;
3256 shapePolygon = std::make_unique< QgsPolygon >();
3260 for (
const QPolygonF &ring : *rings )
3266 shapeEngine->prepareGeometry();
3273 path.addPolygon( points );
3276 for (
const QPolygonF &ring : *rings )
3278 path.addPolygon( ring );
3281 p->setClipPath( path, Qt::IntersectClip );
3287 const QRectF boundingRect = points.boundingRect();
3289 QTransform invertedRotateTransform;
3295 QTransform transform;
3296 if ( applyBrushTransform )
3299 transform.translate( -boundingRect.center().x(),
3300 -boundingRect.center().y() );
3302 transform.translate( boundingRect.center().x(),
3303 boundingRect.center().y() );
3311 const QRectF transformedBounds = transform.map( points ).boundingRect();
3315 left = transformedBounds.left() - buffer * 2;
3316 top = transformedBounds.top() - buffer * 2;
3317 right = transformedBounds.right() + buffer * 2;
3318 bottom = transformedBounds.bottom() + buffer * 2;
3319 invertedRotateTransform = transform.inverted();
3321 if ( !applyBrushTransform )
3323 top -= transformedBounds.top() - ( outputPixelDistance * std::floor( transformedBounds.top() / outputPixelDistance ) );
3328 const bool needsExpressionContext = mFillLineSymbol->hasDataDefinedProperties();
3333 int currentLine = 0;
3334 for (
double currentY = top; currentY <= bottom; currentY += outputPixelDistance )
3339 if ( needsExpressionContext )
3343 double y1 = currentY;
3345 double y2 = currentY;
3346 invertedRotateTransform.map( left, currentY - outputPixelOffset, &x1, &y1 );
3347 invertedRotateTransform.map( right, currentY - outputPixelOffset, &x2, &y2 );
3352 std::unique_ptr< QgsAbstractGeometry > intersection( shapeEngine->intersection( &ls ) );
3353 for (
auto it = intersection->const_parts_begin(); it != intersection->const_parts_end(); ++it )
3355 if (
const QgsLineString *ls = qgsgeometry_cast< const QgsLineString * >( *it ) )
3363 mFillLineSymbol->renderPolyline( QPolygonF() << QPointF( x1, y1 ) << QPointF( x2, y2 ), context.
feature(), context.
renderContext() );
3375 map.insert( QStringLiteral(
"angle" ), QString::number( mLineAngle ) );
3376 map.insert( QStringLiteral(
"distance" ), QString::number( mDistance ) );
3377 map.insert( QStringLiteral(
"line_width" ), QString::number( mLineWidth ) );
3379 map.insert( QStringLiteral(
"offset" ), QString::number( mOffset ) );
3395 if ( mFillLineSymbol )
3406 QDomElement symbolizerElem = doc.createElement( QStringLiteral(
"se:PolygonSymbolizer" ) );
3407 if ( !props.value( QStringLiteral(
"uom" ), QString() ).toString().isEmpty() )
3408 symbolizerElem.setAttribute( QStringLiteral(
"uom" ), props.value( QStringLiteral(
"uom" ), QString() ).toString() );
3409 element.appendChild( symbolizerElem );
3414 QDomElement fillElem = doc.createElement( QStringLiteral(
"se:Fill" ) );
3415 symbolizerElem.appendChild( fillElem );
3417 QDomElement graphicFillElem = doc.createElement( QStringLiteral(
"se:GraphicFill" ) );
3418 fillElem.appendChild( graphicFillElem );
3420 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
3421 graphicFillElem.appendChild( graphicElem );
3426 bool exportOk {
false };
3430 if ( ! image.isNull() )
3432 const QFileInfo info { context.exportFilePath() };
3433 QString pngPath { info.completeSuffix().isEmpty() ? context.exportFilePath() : context.exportFilePath().chopped( info.completeSuffix().length() ).append( QStringLiteral(
"png" ) ) };
3435 image.save( pngPath );
3444 QColor lineColor = mFillLineSymbol ? mFillLineSymbol->color() : QColor();
3445 double lineWidth = mFillLineSymbol ? mFillLineSymbol->width() : 0.0;
3453 double angle = props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toDouble( &ok );
3456 angleFunc = QStringLiteral(
"%1 + %2" ).arg( props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toString() ).arg( mLineAngle );
3460 angleFunc = QString::number(
angle + mLineAngle );
3465 QPointF lineOffset( std::sin( mLineAngle ) * mOffset, std::cos( mLineAngle ) * mOffset );
3473 QString featureStyle;
3474 featureStyle.append(
"Brush(" );
3475 featureStyle.append( QStringLiteral(
"fc:%1" ).arg(
mColor.name() ) );
3476 featureStyle.append( QStringLiteral(
",bc:%1" ).arg( QLatin1String(
"#00000000" ) ) );
3477 featureStyle.append(
",id:\"ogr-brush-2\"" );
3478 featureStyle.append( QStringLiteral(
",a:%1" ).arg( mLineAngle ) );
3479 featureStyle.append( QStringLiteral(
",s:%1" ).arg( mLineWidth * widthScaleFactor ) );
3480 featureStyle.append(
",dx:0mm" );
3481 featureStyle.append( QStringLiteral(
",dy:%1mm" ).arg( mDistance * widthScaleFactor ) );
3482 featureStyle.append(
')' );
3483 return featureStyle;
3489 && ( !mFillLineSymbol || !mFillLineSymbol->hasDataDefinedProperties() ) )
3514 Qt::PenStyle lineStyle;
3516 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
3517 if ( fillElem.isNull() )
3520 QDomElement graphicFillElem = fillElem.firstChildElement( QStringLiteral(
"GraphicFill" ) );
3521 if ( graphicFillElem.isNull() )
3524 QDomElement graphicElem = graphicFillElem.firstChildElement( QStringLiteral(
"Graphic" ) );
3525 if ( graphicElem.isNull() )
3531 if ( name != QLatin1String(
"horline" ) )
3539 double d = angleFunc.toDouble( &ok );
3548 offset = std::sqrt( std::pow( vectOffset.x(), 2 ) + std::pow( vectOffset.y(), 2 ) );
3551 double scaleFactor = 1.0;
3552 const QString uom = element.attribute( QStringLiteral(
"uom" ) );
3554 size = size * scaleFactor;
3557 std::unique_ptr< QgsLinePatternFillSymbolLayer > sl = std::make_unique< QgsLinePatternFillSymbolLayer >();
3558 sl->setOutputUnit( sldUnitSize );
3559 sl->setColor( lineColor );
3561 sl->setLineAngle(
angle );
3563 sl->setDistance( size );
3566 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
3567 if ( !strokeElem.isNull() )
3578 return sl.release();
3678 std::unique_ptr< QgsPointPatternFillSymbolLayer > layer = std::make_unique< QgsPointPatternFillSymbolLayer >();
3679 if (
properties.contains( QStringLiteral(
"distance_x" ) ) )
3681 layer->setDistanceX(
properties[QStringLiteral(
"distance_x" )].toDouble() );
3683 if (
properties.contains( QStringLiteral(
"distance_y" ) ) )
3685 layer->setDistanceY(
properties[QStringLiteral(
"distance_y" )].toDouble() );
3687 if (
properties.contains( QStringLiteral(
"displacement_x" ) ) )
3689 layer->setDisplacementX(
properties[QStringLiteral(
"displacement_x" )].toDouble() );
3691 if (
properties.contains( QStringLiteral(
"displacement_y" ) ) )
3693 layer->setDisplacementY(
properties[QStringLiteral(
"displacement_y" )].toDouble() );
3695 if (
properties.contains( QStringLiteral(
"offset_x" ) ) )
3697 layer->setOffsetX(
properties[QStringLiteral(
"offset_x" )].toDouble() );
3699 if (
properties.contains( QStringLiteral(
"offset_y" ) ) )
3701 layer->setOffsetY(
properties[QStringLiteral(
"offset_y" )].toDouble() );
3704 if (
properties.contains( QStringLiteral(
"distance_x_unit" ) ) )
3708 if (
properties.contains( QStringLiteral(
"distance_x_map_unit_scale" ) ) )
3712 if (
properties.contains( QStringLiteral(
"distance_y_unit" ) ) )
3716 if (
properties.contains( QStringLiteral(
"distance_y_map_unit_scale" ) ) )
3720 if (
properties.contains( QStringLiteral(
"displacement_x_unit" ) ) )
3724 if (
properties.contains( QStringLiteral(
"displacement_x_map_unit_scale" ) ) )
3728 if (
properties.contains( QStringLiteral(
"displacement_y_unit" ) ) )
3732 if (
properties.contains( QStringLiteral(
"displacement_y_map_unit_scale" ) ) )
3736 if (
properties.contains( QStringLiteral(
"offset_x_unit" ) ) )
3740 if (
properties.contains( QStringLiteral(
"offset_x_map_unit_scale" ) ) )
3744 if (
properties.contains( QStringLiteral(
"offset_y_unit" ) ) )
3748 if (
properties.contains( QStringLiteral(
"offset_y_map_unit_scale" ) ) )
3753 if (
properties.contains( QStringLiteral(
"random_deviation_x" ) ) )
3755 layer->setMaximumRandomDeviationX(
properties[QStringLiteral(
"random_deviation_x" )].toDouble() );
3757 if (
properties.contains( QStringLiteral(
"random_deviation_y" ) ) )
3759 layer->setMaximumRandomDeviationY(
properties[QStringLiteral(
"random_deviation_y" )].toDouble() );
3761 if (
properties.contains( QStringLiteral(
"random_deviation_x_unit" ) ) )
3765 if (
properties.contains( QStringLiteral(
"random_deviation_x_map_unit_scale" ) ) )
3769 if (
properties.contains( QStringLiteral(
"random_deviation_y_unit" ) ) )
3773 if (
properties.contains( QStringLiteral(
"random_deviation_y_map_unit_scale" ) ) )
3777 unsigned long seed = 0;
3778 if (
properties.contains( QStringLiteral(
"seed" ) ) )
3784 std::random_device rd;
3785 std::mt19937 mt(
seed == 0 ? rd() :
seed );
3786 std::uniform_int_distribution<> uniformDist( 1, 999999999 );
3787 seed = uniformDist( mt );
3789 layer->setSeed(
seed );
3791 if (
properties.contains( QStringLiteral(
"outline_width_unit" ) ) )
3795 if (
properties.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
3799 if (
properties.contains( QStringLiteral(
"clip_mode" ) ) )
3803 if (
properties.contains( QStringLiteral(
"coordinate_reference" ) ) )
3808 if (
properties.contains( QStringLiteral(
"angle" ) ) )
3810 layer->setAngle(
properties[QStringLiteral(
"angle" )].toDouble() );
3813 layer->restoreOldDataDefinedProperties(
properties );
3815 return layer.release();
3820 return QStringLiteral(
"PointPatternFill" );
3823bool QgsPointPatternFillSymbolLayer::applyPattern(
const QgsSymbolRenderContext &context, QBrush &brush,
double distanceX,
double distanceY,
3824 double displacementX,
double displacementY,
double offsetX,
double offsetY )
3831 double widthOffset = std::fmod(
3834 double heightOffset = std::fmod(
3838 if ( width > 2000 || height > 2000 )
3840 brush.setTextureImage( QImage() );
3844 QImage patternImage( width, height, QImage::Format_ARGB32 );
3845 patternImage.fill( 0 );
3846 if ( patternImage.isNull() )
3848 brush.setTextureImage( QImage() );
3853 QPainter p( &patternImage );
3871 for (
double currentX = -width; currentX <= width * 2.0; currentX += width )
3873 for (
double currentY = -height; currentY <= height * 2.0; currentY += height )
3875 mMarkerSymbol->renderPoint( QPointF( currentX + widthOffset, currentY + heightOffset ), context.
feature(), pointRenderContext );
3886 for (
double currentX = -width; currentX <= width * 2.0; currentX += width )
3888 for (
double currentY = -height / 2.0; currentY <= height * 2.0; currentY += height )
3890 mMarkerSymbol->renderPoint( QPointF( currentX + widthOffset + displacementPixelX, currentY + heightOffset ), context.
feature(), pointRenderContext );
3894 for (
double currentX = -width / 2.0; currentX <= width * 2.0; currentX += width )
3896 for (
double currentY = -height; currentY <= height * 2.0; currentY += height / 2.0 )
3898 mMarkerSymbol->renderPoint( QPointF( currentX + widthOffset + ( std::fmod( currentY, height ) != 0 ? displacementPixelX : 0 ), currentY + heightOffset - displacementPixelY ), context.feature(), pointRenderContext );
3907 QImage transparentImage = patternImage.copy();
3909 brush.setTextureImage( transparentImage );
3913 brush.setTextureImage( patternImage );
3915 QTransform brushTransform;
3916 brush.setTransform( brushTransform );
3936 if ( !mRenderUsingMarkers )
3943 if ( mRenderUsingMarkers )
3951 if ( mRenderUsingMarkers )
3977 if ( !mRenderUsingMarkers )
4020 const double widthOffset = std::fmod(
4032 const double heightOffset = std::fmod(
4058 p->setPen( QPen( Qt::NoPen ) );
4061 if ( useSelectedColor )
4064 p->setBrush( QBrush( selColor ) );
4088 std::unique_ptr< QgsPolygon > shapePolygon;
4089 std::unique_ptr< QgsGeometryEngine > shapeEngine;
4096 shapePolygon = std::make_unique< QgsPolygon >();
4100 for (
const QPolygonF &ring : *rings )
4106 shapeEngine->prepareGeometry();
4113 path.addPolygon( points );
4116 for (
const QPolygonF &ring : *rings )
4118 path.addPolygon( ring );
4121 p->setClipPath( path, Qt::IntersectClip );
4127 const QRectF boundingRect = points.boundingRect();
4129 QTransform invertedRotateTransform;
4137 QTransform transform;
4138 if ( applyBrushTransform )
4141 transform.translate( -boundingRect.center().x(),
4142 -boundingRect.center().y() );
4143 transform.rotate( -
angle );
4144 transform.translate( boundingRect.center().x(),
4145 boundingRect.center().y() );
4150 transform.rotate( -
angle );
4153 const QRectF transformedBounds = transform.map( points ).boundingRect();
4154 left = transformedBounds.left() - 2 * width;
4155 top = transformedBounds.top() - 2 * height;
4156 right = transformedBounds.right() + 2 * width;
4157 bottom = transformedBounds.bottom() + 2 * height;
4158 invertedRotateTransform = transform.inverted();
4160 if ( !applyBrushTransform )
4162 left -= transformedBounds.left() - ( width * std::floor( transformedBounds.left() / width ) );
4163 top -= transformedBounds.top() - ( height * std::floor( transformedBounds.top() / height ) );
4168 left = boundingRect.left() - 2 * width;
4169 top = boundingRect.top() - 2 * height;
4170 right = boundingRect.right() + 2 * width;
4171 bottom = boundingRect.bottom() + 2 * height;
4173 if ( !applyBrushTransform )
4175 left -= boundingRect.left() - ( width * std::floor( boundingRect.left() / width ) );
4176 top -= boundingRect.top() - ( height * std::floor( boundingRect.top() / height ) );
4205 std::random_device rd;
4206 std::mt19937 mt(
seed == 0 ? rd() :
seed );
4207 std::uniform_real_distribution<> uniformDist( 0, 1 );
4213 const bool needsExpressionContext =
mMarkerSymbol->hasDataDefinedProperties();
4221 bool alternateColumn =
false;
4222 int currentCol = -3;
4223 for (
double currentX = left; currentX <= right; currentX += width, alternateColumn = !alternateColumn )
4228 if ( needsExpressionContext )
4231 bool alternateRow =
false;
4232 const double columnX = currentX + widthOffset;
4233 int currentRow = -3;
4234 for (
double currentY = top; currentY <= bottom; currentY += height, alternateRow = !alternateRow )
4239 double y = currentY + heightOffset;
4242 x += displacementPixelX;
4244 if ( !alternateColumn )
4245 y -= displacementPixelY;
4251 invertedRotateTransform.map( xx, yy, &x, &y );
4254 if ( useRandomShift )
4256 x += ( 2 * uniformDist( mt ) - 1 ) * maxRandomDeviationPixelX;
4257 y += ( 2 * uniformDist( mt ) - 1 ) * maxRandomDeviationPixelY;
4260 if ( needsExpressionContext )
4268 bool renderPoint =
true;
4276 renderPoint = shapeEngine->intersects( &p );
4288 renderPoint = shapeEngine->intersects( markerBounds.
constGet() );
4314 map.insert( QStringLiteral(
"distance_x" ), QString::number(
mDistanceX ) );
4315 map.insert( QStringLiteral(
"distance_y" ), QString::number(
mDistanceY ) );
4316 map.insert( QStringLiteral(
"displacement_x" ), QString::number(
mDisplacementX ) );
4317 map.insert( QStringLiteral(
"displacement_y" ), QString::number(
mDisplacementY ) );
4318 map.insert( QStringLiteral(
"offset_x" ), QString::number(
mOffsetX ) );
4319 map.insert( QStringLiteral(
"offset_y" ), QString::number(
mOffsetY ) );
4335 map.insert( QStringLiteral(
"random_deviation_x" ), QString::number(
mRandomDeviationX ) );
4336 map.insert( QStringLiteral(
"random_deviation_y" ), QString::number(
mRandomDeviationY ) );
4341 map.insert( QStringLiteral(
"seed" ), QString::number(
mSeed ) );
4342 map.insert( QStringLiteral(
"angle" ),
mAngle );
4361 for (
int symbolLayerIdx = 0; symbolLayerIdx <
mMarkerSymbol->symbolLayerCount(); symbolLayerIdx++ )
4363 QDomElement symbolizerElem = doc.createElement( QStringLiteral(
"se:PolygonSymbolizer" ) );
4364 if ( !props.value( QStringLiteral(
"uom" ), QString() ).toString().isEmpty() )
4365 symbolizerElem.setAttribute( QStringLiteral(
"uom" ), props.value( QStringLiteral(
"uom" ), QString() ).toString() );
4366 element.appendChild( symbolizerElem );
4371 QDomElement fillElem = doc.createElement( QStringLiteral(
"se:Fill" ) );
4372 symbolizerElem.appendChild( fillElem );
4374 QDomElement graphicFillElem = doc.createElement( QStringLiteral(
"se:GraphicFill" ) );
4375 fillElem.appendChild( graphicFillElem );
4382 bool exportOk {
false };
4386 if ( ! image.isNull() )
4388 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
4389 graphicFillElem.appendChild( graphicElem );
4390 const QFileInfo info { context.exportFilePath() };
4391 QString pngPath { info.completeSuffix().isEmpty() ? context.exportFilePath() : context.exportFilePath().chopped( info.completeSuffix().length() ).append( QStringLiteral(
"png" ) ) };
4393 image.save( pngPath );
4412 symbolizerElem.appendChild( graphicMarginElem );
4416 markerLayer->writeSldMarker( doc, graphicFillElem, props );
4420 QString errorMsg = QStringLiteral(
"QgsMarkerSymbolLayer expected, %1 found. Skip it." ).arg( layer->
layerType() );
4421 graphicFillElem.appendChild( doc.createComment( errorMsg ) );
4425 QString errorMsg = QStringLiteral(
"Missing point pattern symbol layer. Skip it." );
4426 graphicFillElem.appendChild( doc.createComment( errorMsg ) );
4435 double angleRads { qDegreesToRadians(
mAngle ) };
4444 if ( displacementXPx != 0 )
4449 if ( displacementYPx != 0 )
4456 QPixmap pixmap( size );
4457 pixmap.fill( Qt::transparent );
4459 painter.begin( &pixmap );
4460 painter.setRenderHint( QPainter::Antialiasing );
4468 std::unique_ptr< QgsPointPatternFillSymbolLayer > layerClone(
clone() );
4470 layerClone->setAngle( qRadiansToDegrees( angleRads ) );
4473 layerClone->setMaximumRandomDeviationX( 0 );
4474 layerClone->setMaximumRandomDeviationY( 0 );
4476 layerClone->drawPreviewIcon( symbolContext, pixmap.size() );
4478 return pixmap.toImage();
4486 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
4487 if ( fillElem.isNull() )
4490 QDomElement graphicFillElem = fillElem.firstChildElement( QStringLiteral(
"GraphicFill" ) );
4491 if ( graphicFillElem.isNull() )
4494 QDomElement graphicElem = graphicFillElem.firstChildElement( QStringLiteral(
"Graphic" ) );
4495 if ( graphicElem.isNull() )
4499 if ( !simpleMarkerSl )
4504 layers.append( simpleMarkerSl );
4506 std::unique_ptr< QgsMarkerSymbol > marker = std::make_unique< QgsMarkerSymbol >( layers );
4509 const double markerSize { marker->size() };
4511 std::unique_ptr< QgsPointPatternFillSymbolLayer > pointPatternFillSl = std::make_unique< QgsPointPatternFillSymbolLayer >();
4512 pointPatternFillSl->setSubSymbol( marker.release() );
4517 auto distanceParser = [ & ](
const QStringList & values )
4519 switch ( values.count( ) )
4524 const double v { values.at( 0 ).toDouble( &ok ) };
4527 pointPatternFillSl->setDistanceX( v * 2 + markerSize );
4528 pointPatternFillSl->setDistanceY( v * 2 + markerSize );
4535 const double vX { values.at( 1 ).toDouble( &ok ) };
4538 pointPatternFillSl->setDistanceX( vX * 2 + markerSize );
4540 const double vY { values.at( 0 ).toDouble( &ok ) };
4543 pointPatternFillSl->setDistanceY( vY * 2 + markerSize );
4550 const double vX { values.at( 1 ).toDouble( &ok ) };
4553 pointPatternFillSl->setDistanceX( vX * 2 + markerSize );
4555 const double vYt { values.at( 0 ).toDouble( &ok ) };
4558 const double vYb { values.at( 2 ).toDouble( &ok ) };
4561 pointPatternFillSl->setDistanceY( ( vYt + vYb ) + markerSize );
4569 const double vYt { values.at( 0 ).toDouble( &ok ) };
4572 const double vYb { values.at( 2 ).toDouble( &ok ) };
4575 pointPatternFillSl->setDistanceY( ( vYt + vYb ) + markerSize );
4578 const double vXr { values.at( 1 ).toDouble( &ok ) };
4581 const double vXl { values.at( 3 ).toDouble( &ok ) };
4584 pointPatternFillSl->setDistanceX( ( vXr + vXl ) + markerSize );
4595 bool distanceFromVendorOption {
false };
4597 for ( QgsStringMap::iterator it = vendorOptions.begin(); it != vendorOptions.end(); ++it )
4600 if ( it.key() == QLatin1String(
"distance" ) )
4602 distanceParser( it.value().split(
',' ) );
4603 distanceFromVendorOption =
true;
4606 else if ( it.key() == QLatin1String(
"graphic-margin" ) )
4608 distanceParser( it.value().split(
' ' ) );
4609 distanceFromVendorOption =
true;
4614 if ( ! distanceFromVendorOption && ! graphicFillElem.elementsByTagName( QStringLiteral(
"Size" ) ).isEmpty() )
4616 const QDomElement sizeElement { graphicFillElem.elementsByTagName( QStringLiteral(
"Size" ) ).at( 0 ).toElement() };
4618 const double size { sizeElement.text().toDouble( &ok ) };
4621 pointPatternFillSl->setDistanceX( size );
4622 pointPatternFillSl->setDistanceY( size );
4626 return pointPatternFillSl.release();
4708 attributes.unite(
mMarkerSymbol->usedAttributes( context ) );
4746 std::unique_ptr< QgsCentroidFillSymbolLayer > sl = std::make_unique< QgsCentroidFillSymbolLayer >();
4748 if (
properties.contains( QStringLiteral(
"point_on_surface" ) ) )
4749 sl->setPointOnSurface(
properties[QStringLiteral(
"point_on_surface" )].toInt() != 0 );
4750 if (
properties.contains( QStringLiteral(
"point_on_all_parts" ) ) )
4751 sl->setPointOnAllParts(
properties[QStringLiteral(
"point_on_all_parts" )].toInt() != 0 );
4752 if (
properties.contains( QStringLiteral(
"clip_points" ) ) )
4753 sl->setClipPoints(
properties[QStringLiteral(
"clip_points" )].toInt() != 0 );
4754 if (
properties.contains( QStringLiteral(
"clip_on_current_part_only" ) ) )
4755 sl->setClipOnCurrentPartOnly(
properties[QStringLiteral(
"clip_on_current_part_only" )].toInt() != 0 );
4757 sl->restoreOldDataDefinedProperties(
properties );
4759 return sl.release();
4764 return QStringLiteral(
"CentroidFill" );
4791 part.exterior = points;
4793 part.rings = *rings;
4800 mCurrentParts << part;
4805 const double prevOpacity =
mMarker->opacity();
4809 mMarker->setOpacity( prevOpacity );
4818 mCurrentParts.clear();
4825 const double prevOpacity =
mMarker->opacity();
4828 render( context, mCurrentParts, feature,
false );
4830 mMarker->setOpacity( prevOpacity );
4835void QgsCentroidFillSymbolLayer::render(
QgsRenderContext &context,
const QVector<QgsCentroidFillSymbolLayer::Part> &parts,
const QgsFeature &feature,
bool selected )
4844 QVector< QgsGeometry > geometryParts;
4845 geometryParts.reserve( parts.size() );
4846 QPainterPath globalPath;
4849 int maxAreaPartIdx = 0;
4851 for (
int i = 0; i < parts.size(); i++ )
4853 const Part part = parts[i];
4856 if ( !geom.
isNull() && !part.rings.empty() )
4858 QgsPolygon *poly = qgsgeometry_cast< QgsPolygon * >( geom.
get() );
4862 int area = poly->
area();
4864 if ( area > maxArea )
4874 globalPath.addPolygon( part.exterior );
4875 for (
const QPolygonF &ring : part.rings )
4877 globalPath.addPolygon( ring );
4882 for (
int i = 0; i < parts.size(); i++ )
4887 const Part part = parts[i];
4895 path.addPolygon( part.exterior );
4896 for (
const QPolygonF &ring : part.rings )
4898 path.addPolygon( ring );
4907 context.
painter()->setClipPath( path );
4914 mMarker->renderPoint( centroid, feature.
isValid() ? &feature : nullptr, context, -1, selected );
4927 map[QStringLiteral(
"point_on_surface" )] = QString::number(
mPointOnSurface );
4928 map[QStringLiteral(
"point_on_all_parts" )] = QString::number(
mPointOnAllParts );
4929 map[QStringLiteral(
"clip_points" )] = QString::number(
mClipPoints );
4936 std::unique_ptr< QgsCentroidFillSymbolLayer > x = std::make_unique< QgsCentroidFillSymbolLayer >();
4939 x->setSubSymbol(
mMarker->clone() );
4954 mMarker->toSld( doc, element, props );
4965 std::unique_ptr< QgsMarkerSymbol > marker(
new QgsMarkerSymbol( layers ) );
4967 std::unique_ptr< QgsCentroidFillSymbolLayer > sl = std::make_unique< QgsCentroidFillSymbolLayer >();
4968 sl->setSubSymbol( marker.release() );
4969 sl->setPointOnAllParts(
false );
4970 return sl.release();
4997 attributes.unite(
mMarker->usedAttributes( context ) );
5020 mMarker->setOutputUnit( unit );
5037 return mMarker->usesMapUnits();
5046 mMarker->setMapUnitScale( scale );
5054 return mMarker->mapUnitScale();
5064 , mImageFilePath( imageFilePath )
5081 if (
properties.contains( QStringLiteral(
"imageFile" ) ) )
5083 imagePath =
properties[QStringLiteral(
"imageFile" )].toString();
5085 if (
properties.contains( QStringLiteral(
"coordinate_mode" ) ) )
5089 if (
properties.contains( QStringLiteral(
"alpha" ) ) )
5091 alpha =
properties[QStringLiteral(
"alpha" )].toDouble();
5093 if (
properties.contains( QStringLiteral(
"offset" ) ) )
5097 if (
properties.contains( QStringLiteral(
"angle" ) ) )
5101 if (
properties.contains( QStringLiteral(
"width" ) ) )
5105 std::unique_ptr< QgsRasterFillSymbolLayer > symbolLayer = std::make_unique< QgsRasterFillSymbolLayer >( imagePath );
5106 symbolLayer->setCoordinateMode( mode );
5107 symbolLayer->setOpacity( alpha );
5108 symbolLayer->setOffset(
offset );
5109 symbolLayer->setAngle(
angle );
5110 symbolLayer->setWidth(
width );
5111 if (
properties.contains( QStringLiteral(
"offset_unit" ) ) )
5115 if (
properties.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
5119 if (
properties.contains( QStringLiteral(
"width_unit" ) ) )
5123 if (
properties.contains( QStringLiteral(
"width_map_unit_scale" ) ) )
5128 symbolLayer->restoreOldDataDefinedProperties(
properties );
5130 return symbolLayer.release();
5135 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
5136 if ( fillElem.isNull() )
5139 QDomElement graphicFillElem = fillElem.firstChildElement( QStringLiteral(
"GraphicFill" ) );
5140 if ( graphicFillElem.isNull() )
5143 QDomElement graphicElem = graphicFillElem.firstChildElement( QStringLiteral(
"Graphic" ) );
5144 if ( graphicElem.isNull() )
5147 QString path, mimeType;
5155 if ( ! QFile::exists( path ) )
5160 std::unique_ptr< QgsRasterFillSymbolLayer> sl = std::make_unique< QgsRasterFillSymbolLayer>( path );
5162 return sl.release();
5167 QVariantMap::iterator it =
properties.find( QStringLiteral(
"imageFile" ) );
5171 it.value() = pathResolver.
writePath( it.value().toString() );
5173 it.value() = pathResolver.
readPath( it.value().toString() );
5185 return QStringLiteral(
"RasterFill" );
5196 QPointF
offset = mOffset;
5214 QRectF boundingRect = points.boundingRect();
5215 mBrush.setTransform(
mBrush.transform().translate( boundingRect.left() -
mBrush.transform().dx(),
5216 boundingRect.top() -
mBrush.transform().dy() ) );
5228 applyPattern(
mBrush, mImageFilePath, mWidth, mOpacity * context.
opacity(), context );
5239 map[QStringLiteral(
"imageFile" )] = mImageFilePath;
5240 map[QStringLiteral(
"coordinate_mode" )] = QString::number(
static_cast< int >( mCoordinateMode ) );
5241 map[QStringLiteral(
"alpha" )] = QString::number( mOpacity );
5245 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
5246 map[QStringLiteral(
"width" )] = QString::number( mWidth );
5254 std::unique_ptr< QgsRasterFillSymbolLayer > sl = std::make_unique< QgsRasterFillSymbolLayer >( mImageFilePath );
5255 sl->setCoordinateMode( mCoordinateMode );
5256 sl->setOpacity( mOpacity );
5257 sl->setOffset( mOffset );
5258 sl->setOffsetUnit( mOffsetUnit );
5259 sl->setOffsetMapUnitScale( mOffsetMapUnitScale );
5261 sl->setWidth( mWidth );
5262 sl->setWidthUnit( mWidthUnit );
5263 sl->setWidthMapUnitScale( mWidthMapUnitScale );
5266 return sl.release();
5271 return context.
convertToPainterUnits( std::max( std::fabs( mOffset.x() ), std::fabs( mOffset.y() ) ), mOffsetUnit, mOffsetMapUnitScale );
5294 mImageFilePath = imagePath;
5299 mCoordinateMode = mode;
5317 if ( !hasWidthExpression && !hasAngleExpression && !hasOpacityExpression && !hasFileExpression )
5323 if ( hasAngleExpression )
5331 if ( !hasWidthExpression && !hasOpacityExpression && !hasFileExpression )
5336 double width = mWidth;
5337 if ( hasWidthExpression )
5343 if ( hasOpacityExpression )
5348 QString file = mImageFilePath;
5349 if ( hasFileExpression )
5362void QgsRasterFillSymbolLayer::applyPattern( QBrush &brush,
const QString &imageFilePath,
const double width,
const double alpha,
const QgsSymbolRenderContext &context )
5375 if ( size.isEmpty() )
5378 size.setWidth( (
width * size.width() ) / 100.0 );
5381 if (
static_cast< int >( size.width() ) < 1 || 10000.0 < size.width() )
5385 size.setHeight( 0 );
5393 brush.setTextureImage( img );
5402 : mCountMethod( method )
5403 , mPointCount( pointCount )
5404 , mDensityArea( densityArea )
5415 const int pointCount =
properties.value( QStringLiteral(
"point_count" ), QStringLiteral(
"10" ) ).toInt();
5416 const double densityArea =
properties.value( QStringLiteral(
"density_area" ), QStringLiteral(
"250.0" ) ).toDouble();
5418 unsigned long seed = 0;
5419 if (
properties.contains( QStringLiteral(
"seed" ) ) )
5425 std::random_device rd;
5426 std::mt19937 mt(
seed == 0 ? rd() :
seed );
5427 std::uniform_int_distribution<> uniformDist( 1, 999999999 );
5428 seed = uniformDist( mt );
5433 if (
properties.contains( QStringLiteral(
"density_area_unit" ) ) )
5435 if (
properties.contains( QStringLiteral(
"density_area_unit_scale" ) ) )
5438 if (
properties.contains( QStringLiteral(
"clip_points" ) ) )
5440 sl->setClipPoints(
properties[QStringLiteral(
"clip_points" )].toInt() );
5443 return sl.release();
5448 return QStringLiteral(
"RandomMarkerFill" );
5453 mMarker->setColor(
color );
5459 return mMarker ? mMarker->color() :
mColor;
5475 part.exterior = points;
5477 part.rings = *rings;
5479 if ( mRenderingFeature )
5483 mFeatureSymbolOpacity = context.
opacity();
5484 mCurrentParts << part;
5489 const double prevOpacity = mMarker->opacity();
5490 mMarker->setOpacity( mMarker->opacity() * context.
opacity() );
5493 mMarker->setOpacity( prevOpacity );
5497void QgsRandomMarkerFillSymbolLayer::render(
QgsRenderContext &context,
const QVector<QgsRandomMarkerFillSymbolLayer::Part> &parts,
const QgsFeature &feature,
bool selected )
5506 QVector< QgsGeometry > geometryParts;
5507 geometryParts.reserve( parts.size() );
5510 for (
const Part &part : parts )
5513 if ( !geom.
isNull() && !part.rings.empty() )
5515 QgsPolygon *poly = qgsgeometry_cast< QgsPolygon * >( geom.
get() );
5516 for (
const QPolygonF &ring : part.rings )
5523 geom = geom.
buffer( 0, 0 );
5525 geometryParts << geom;
5529 path.addPolygon( part.exterior );
5530 for (
const QPolygonF &ring : part.rings )
5532 path.addPolygon( ring );
5542 context.
painter()->setClipPath( path );
5546 int count = mPointCount;
5553 switch ( mCountMethod )
5565 count = std::max( 0.0, std::ceil( count * ( geom.
area() /
densityArea ) ) );
5572 unsigned long seed = mSeed;
5583 std::sort( randomPoints.begin(), randomPoints.end(), [](
const QgsPointXY & a,
const QgsPointXY & b )->bool
5585 return a.y() < b.y();
5591 const bool needsExpressionContext = mMarker->hasDataDefinedProperties();
5596 for (
const QgsPointXY &p : std::as_const( randomPoints ) )
5598 if ( needsExpressionContext )
5600 mMarker->renderPoint( QPointF( p.x(), p.y() ), feature.
isValid() ? &feature : nullptr, context, -1, selected );
5614 map.insert( QStringLiteral(
"count_method" ), QString::number(
static_cast< int >( mCountMethod ) ) );
5615 map.insert( QStringLiteral(
"point_count" ), QString::number( mPointCount ) );
5616 map.insert( QStringLiteral(
"density_area" ), QString::number( mDensityArea ) );
5619 map.insert( QStringLiteral(
"seed" ), QString::number( mSeed ) );
5620 map.insert( QStringLiteral(
"clip_points" ), QString::number( mClipPoints ) );
5626 std::unique_ptr< QgsRandomMarkerFillSymbolLayer > res = std::make_unique< QgsRandomMarkerFillSymbolLayer >( mPointCount, mCountMethod, mDensityArea, mSeed );
5629 res->setDensityAreaUnit( mDensityAreaUnit );
5630 res->setDensityAreaUnitScale( mDensityAreaUnitScale );
5631 res->mClipPoints = mClipPoints;
5632 res->setSubSymbol( mMarker->clone() );
5635 return res.release();
5645 return mMarker.get();
5657 mColor = mMarker->color();
5666 attributes.unite( mMarker->usedAttributes( context ) );
5675 if ( mMarker && mMarker->hasDataDefinedProperties() )
5712 return mCountMethod;
5717 mCountMethod = method;
5722 return mDensityArea;
5727 mDensityArea = area;
5734 mRenderingFeature =
true;
5735 mCurrentParts.clear();
5740 mRenderingFeature =
false;
5742 const double prevOpacity = mMarker->opacity();
5743 mMarker->setOpacity( mMarker->opacity() * mFeatureSymbolOpacity );
5745 render( context, mCurrentParts, feature,
false );
5747 mFeatureSymbolOpacity = 1;
5748 mMarker->setOpacity( prevOpacity );
5756 mDensityAreaUnit = unit;
5759 mMarker->setOutputUnit( unit );
5767 return mMarker->outputUnit();
5776 return mMarker->usesMapUnits();
5785 mMarker->setMapUnitScale( scale );
5793 return mMarker->mapUnitScale();
MarkerClipMode
Marker clipping modes.
@ CompletelyWithin
Render complete markers wherever the completely fall within the polygon shape.
@ NoClipping
No clipping, render complete markers.
@ Shape
Clip to polygon shape.
@ CentroidWithin
Render complete markers wherever their centroid falls within the polygon shape.
LineClipMode
Line clipping modes.
@ NoClipping
Lines are not clipped, will extend to shape's bounding box.
@ ClipPainterOnly
Applying clipping on the painter only (i.e. line endpoints will coincide with polygon bounding box,...
@ ClipToIntersection
Clip lines to intersection with polygon shape (slower) (i.e. line endpoints will coincide with polygo...
GradientColorSource
Gradient color sources.
@ ColorRamp
Gradient color ramp.
@ SimpleTwoColor
Simple two color gradient.
GradientSpread
Gradient spread options, which control how gradients are rendered outside of their start and end poin...
@ Reflect
Reflect gradient.
@ Pad
Pad out gradient using colors at endpoint of gradient.
@ Png
Export complex styles to separate PNG files for better compatibility with OGC servers.
PointCountMethod
Methods which define the number of points randomly filling a polygon.
@ Absolute
The point count is used as an absolute count of markers.
@ DensityBased
The point count is part of a marker density count.
RenderUnit
Rendering size units.
@ Percentage
Percentage of another measurement (e.g., canvas size, feature size)
@ Unknown
Mixed or unknown units.
@ MetersInMapUnits
Meters value as Map units.
@ RenderingSubSymbol
Set whenever a sub-symbol of a parent symbol is currently being rendered. Can be used during symbol a...
@ RenderSymbolPreview
The render is for a symbol preview only and map based properties may not be available,...
@ RenderMapTile
Draw map such that there are no problems between adjacent tiles.
@ HighQualityImageTransforms
Enable high quality image transformations, which results in better appearance of scaled or rotated ra...
@ RenderBlocking
Render and load remote sources in the same thread to ensure rendering remote sources (svg and images)...
GradientType
Gradient types.
@ Conical
Conical (polar) gradient.
@ Radial
Radial (circular) gradient.
SymbolCoordinateReference
Symbol coordinate reference modes.
@ Feature
Relative to feature/shape being rendered.
@ Viewport
Relative to the whole viewport/output device.
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.
int valueAsInt(int key, const QgsExpressionContext &context, int defaultValue=0, bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as an integer.
bool valueAsBool(int key, const QgsExpressionContext &context, bool defaultValue=false, bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as an boolean.
double valueAsDouble(int key, const QgsExpressionContext &context, double defaultValue=0.0, bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a double.
QString valueAsString(int key, const QgsExpressionContext &context, const QString &defaultString=QString(), bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a string.
static QgsImageCache * imageCache()
Returns the application's image cache, used for caching resampled versions of raster images.
static QgsSvgCache * svgCache()
Returns the application's SVG cache, used for caching SVG images and handling parameter replacement w...
static QgsSymbolLayer * createFromSld(QDomElement &element)
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
QgsSymbol * subSymbol() override
Returns the symbol's sub symbol, if present.
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer's subsymbol. takes ownership of the passed symbol.
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
void setMapUnitScale(const QgsMapUnitScale &scale) override
bool canCauseArtifactsBetweenAdjacentTiles() const override
Returns true if the symbol layer rendering can cause visible artifacts across a single feature when t...
bool pointOnSurface() const
QgsMapUnitScale mapUnitScale() const override
void startFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called before the layer will be rendered for a particular feature.
std::unique_ptr< QgsMarkerSymbol > mMarker
QString layerType() const override
Returns a string that represents this layer type.
void setColor(const QColor &color) override
Sets the "representative" color for the symbol layer.
bool pointOnAllParts() const
Returns whether a point is drawn for all parts or only on the biggest part of multi-part features.
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
bool hasDataDefinedProperties() const override
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
void stopFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called after the layer has been rendered for a particular feature.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
bool clipPoints() const
Returns true if point markers should be clipped to the polygon boundary.
QgsCentroidFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
void toSld(QDomDocument &doc, QDomElement &element, const QVariantMap &props) const override
Saves the symbol layer as SLD.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsCentroidFillSymbolLayer using the specified properties map containing symbol propert...
~QgsCentroidFillSymbolLayer() override
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
double mFeatureSymbolOpacity
QgsCentroidFillSymbolLayer()
QColor color() const override
Returns the "representative" color of the symbol layer.
bool clipOnCurrentPartOnly() const
Returns true if point markers should be clipped to the current part boundary only.
bool mClipOnCurrentPartOnly
Abstract base class for color ramps.
virtual QColor color(double value) const =0
Returns the color corresponding to a specified value.
virtual QVariantMap properties() const =0
Returns a string map containing all the color ramp's properties.
virtual QgsColorRamp * clone() const =0
Creates a clone of the color ramp.
virtual QString type() const =0
Returns a string representing the color ramp type.
static QgsColorRamp * create(const QVariantMap &properties=QVariantMap())
Creates the symbol layer.
static QString typeString()
Returns the string identifier for QgsCptCityColorRamp.
double area() const override
Returns the planar, 2-dimensional area of the geometry.
Exports QGIS layers to the DXF format.
static double mapUnitScaleFactor(double scale, Qgis::RenderUnit symbolUnits, Qgis::DistanceUnit mapUnits, double mapUnitsPerPixel=1.0)
Returns scale factor for conversion to map units.
Qgis::DistanceUnit mapUnits() const
Retrieve map units.
double symbologyScale() const
Returns the reference scale for output.
RAII class to pop scope from an expression context on destruction.
Single scope for storing variables and functions for use within a QgsExpressionContext.
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
static const QString EXPR_GEOMETRY_POINT_NUM
Inbuilt variable name for point number variable.
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for the context.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
bool isValid() const
Returns the validity of this feature.
bool isCanceled() const
Tells whether the operation has been canceled already.
static QString uniquePath(const QString &path)
Creates a unique file path name from a desired path by appending "_<n>" (where "<n>" is an integer nu...
void _renderPolygon(QPainter *p, const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context)
Default method to render polygon.
double angle() const
Returns the rotation angle of the fill symbol, in degrees clockwise.
A geometry is the spatial representation of a feature.
QVector< QgsPointXY > randomPointsInPolygon(int count, const std::function< bool(const QgsPointXY &) > &acceptPoint, unsigned long seed=0, QgsFeedback *feedback=nullptr, int maxTriesPerPoint=0) const
Returns a list of count random points generated inside a (multi)polygon geometry (if acceptPoint is s...
static QgsGeometry fromRect(const QgsRectangle &rect)
Creates a new geometry from a QgsRectangle.
static QgsGeometry fromQPolygonF(const QPolygonF &polygon)
Construct geometry from a QPolygonF.
QgsAbstractGeometry * get()
Returns a modifiable (non-const) reference to the underlying abstract geometry primitive.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
bool contains(const QgsPointXY *p) const
Returns true if the geometry contains the point p.
bool isGeosValid(Qgis::GeometryValidityFlags flags=Qgis::GeometryValidityFlags()) const
Checks validity of the geometry using GEOS.
double area() const
Returns the planar, 2-dimensional area of the geometry.
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometry *geometry)
Creates and returns a new geometry engine representing the specified geometry.
QgsGeometry buffer(double distance, int segments) const
Returns a buffer region around this geometry having the given width and with a specified number of se...
static QgsGeometry unaryUnion(const QVector< QgsGeometry > &geometries, const QgsGeometryParameters ¶meters=QgsGeometryParameters())
Compute the unary union on a list of geometries.
Gradient color ramp, which smoothly interpolates between two colors and also supports optional extra ...
static QgsColorRamp * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsColorRamp from a map of properties.
static QString typeString()
Returns the string identifier for QgsGradientColorRamp.
void addStopsToGradient(QGradient *gradient, double opacity=1) const
Copy color ramp stops to a QGradient.
void setColorRamp(QgsColorRamp *ramp)
Sets the color ramp used for the gradient fill.
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
QColor color2() const
Returns the color for endpoint of gradient, only used if the gradient color type is set to SimpleTwoC...
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
bool canCauseArtifactsBetweenAdjacentTiles() const override
Returns true if the symbol layer rendering can cause visible artifacts across a single feature when t...
QgsGradientFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
QgsMapUnitScale mapUnitScale() const override
bool mReferencePoint1IsCentroid
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
Qgis::SymbolCoordinateReference coordinateMode() const
Returns the coordinate mode for gradient, which controls how the gradient stops are positioned.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
Qgis::SymbolCoordinateReference mCoordinateMode
QgsGradientFillSymbolLayer(const QColor &color=DEFAULT_SIMPLEFILL_COLOR, const QColor &color2=Qt::white, Qgis::GradientColorSource gradientColorType=Qgis::GradientColorSource::SimpleTwoColor, Qgis::GradientType gradientType=Qgis::GradientType::Linear, Qgis::SymbolCoordinateReference coordinateMode=Qgis::SymbolCoordinateReference::Feature, Qgis::GradientSpread gradientSpread=Qgis::GradientSpread::Pad)
Constructor for QgsGradientFillSymbolLayer.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsGradientFillSymbolLayer using the specified properties map containing symbol propert...
void setMapUnitScale(const QgsMapUnitScale &scale) override
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
Qgis::GradientSpread mGradientSpread
~QgsGradientFillSymbolLayer() override
Qgis::GradientType mGradientType
QgsColorRamp * mGradientRamp
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QPointF referencePoint1() const
Returns the starting point of gradient fill, in the range [0,0] - [1,1].
Qgis::GradientSpread gradientSpread() const
Returns the gradient spread mode, which controls how the gradient behaves outside of the predefined s...
bool mReferencePoint2IsCentroid
QgsMapUnitScale mOffsetMapUnitScale
Qgis::GradientColorSource gradientColorType() const
Returns the gradient color mode, which controls how gradient color stops are created.
QPointF offset() const
Returns the offset by which polygons will be translated during rendering.
Qgis::GradientColorSource mGradientColorType
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
QString layerType() const override
Returns a string that represents this layer type.
Qgis::RenderUnit mOffsetUnit
Qgis::GradientType gradientType() const
Returns the type of gradient, e.g., linear or radial.
QPointF referencePoint2() const
Returns the end point of gradient fill, in the range [0,0] - [1,1].
QSize originalSize(const QString &path, bool blocking=false) const
Returns the original size (in pixels) of the image at the specified path.
QImage pathAsImage(const QString &path, const QSize size, const bool keepAspectRatio, const double opacity, bool &fitsInCache, bool blocking=false, double targetDpi=96, int frameNumber=-1, bool *isMissing=nullptr)
Returns the specified path rendered as an image.
Base class for polygon renderers generating texture images.
QgsMapUnitScale mStrokeWidthMapUnitScale
QgsImageFillSymbolLayer()
Qgis::SymbolCoordinateReference coordinateReference() const
Returns the coordinate reference mode for fill which controls how the top left corner of the image fi...
double mStrokeWidth
Stroke width.
Qgis::SymbolCoordinateReference mCoordinateReference
double dxfWidth(const QgsDxfExport &e, QgsSymbolRenderContext &context) const override
Gets line width.
QgsMapUnitScale mapUnitScale() const override
Qt::PenStyle dxfPenStyle() const override
Gets pen style.
Qgis::RenderUnit mStrokeWidthUnit
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
void setMapUnitScale(const QgsMapUnitScale &scale) override
virtual void applyDataDefinedSettings(QgsSymbolRenderContext &context)
Applies data defined settings prior to generating the fill symbol brush.
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
~QgsImageFillSymbolLayer() override
virtual bool applyBrushTransformFromContext(QgsSymbolRenderContext *context=nullptr) const
Returns true if the image brush should be transformed using the render context's texture origin.
static void multiplyOpacity(QImage &image, double factor, QgsFeedback *feedback=nullptr)
Multiplies opacity of image pixel values by a factor.
static void stackBlur(QImage &image, int radius, bool alphaOnly=false, QgsFeedback *feedback=nullptr)
Performs a stack blur on an image.
A symbol fill consisting of repeated parallel lines.
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
QgsMapUnitScale mapUnitScale() const override
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
QString layerType() const override
Returns a string that represents this layer type.
QgsLinePatternFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
void stopFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called after the layer has been rendered for a particular feature.
void startFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called before the layer will be rendered for a particular feature.
QColor color() const override
Returns the "representative" color of the symbol layer.
void toSld(QDomDocument &doc, QDomElement &element, const QVariantMap &props) const override
Saves the symbol layer as SLD.
double lineWidth() const
Returns the width of the line subsymbol used to render the parallel lines in the fill.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
void setMapUnitScale(const QgsMapUnitScale &scale) override
Qgis::LineClipMode clipMode() const
Returns the line clipping mode, which defines how lines are clipped at the edges of shapes.
double lineAngle() const
Returns the angle for the parallel lines used to fill the symbol.
void setLineWidth(double w)
Sets the width of the line subsymbol used to render the parallel lines in the fill.
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
void applyDataDefinedSettings(QgsSymbolRenderContext &context) override
Applies data defined settings prior to generating the fill symbol brush.
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer's subsymbol. takes ownership of the passed symbol.
QgsSymbol * subSymbol() override
Returns the symbol's sub symbol, if present.
bool hasDataDefinedProperties() const override
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
void setColor(const QColor &c) override
Sets the "representative" color for the symbol layer.
QImage toTiledPatternImage() const override
Renders the symbol layer as an image that can be used as a seamless pattern fill for polygons,...
double offset() const
Returns the offset distance for lines within the fill, which is the distance to offset the parallel l...
QgsLinePatternFillSymbolLayer()
double distance() const
Returns the distance between lines in the fill pattern.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QString ogrFeatureStyleWidth(double widthScaleFactor) const
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
~QgsLinePatternFillSymbolLayer() override
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
static QgsSymbolLayer * createFromSld(QDomElement &element)
Creates a new QgsLinePatternFillSymbolLayer from a SLD element.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsLinePatternFillSymbolLayer from a properties map.
Line string geometry type, with support for z-dimension and m-values.
QPolygonF asQPolygonF() const override
Returns a QPolygonF representing the points.
static QgsLineString * fromQPolygonF(const QPolygonF &polygon)
Returns a new linestring from a QPolygonF polygon input.
A line symbol type, for rendering LineString and MultiLineString geometries.
Perform transforms between map coordinates and device coordinates.
double mapUnitsPerPixel() const
Returns the current map units per pixel.
Struct for storing maximum and minimum scales for measurements in map units.
Line symbol layer type which draws repeating marker symbols along a line feature.
Abstract base class for marker symbol layers.
A marker symbol type, for rendering Point and MultiPoint geometries.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
Resolves relative paths into absolute paths and vice versa.
QString writePath(const QString &filename) const
Prepare a filename to save it to the project file.
QString readPath(const QString &filename) const
Turn filename read from the project file to an absolute path.
A fill symbol layer which fills polygon shapes with repeating marker symbols.
QgsMapUnitScale mapUnitScale() const override
QgsMapUnitScale mDisplacementYMapUnitScale
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
QgsMapUnitScale mDisplacementXMapUnitScale
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
double distanceX() const
Returns the horizontal distance between rendered markers in the fill.
QgsMapUnitScale mDistanceYMapUnitScale
QImage toTiledPatternImage() const override
Renders the symbol layer as an image that can be used as a seamless pattern fill for polygons,...
double displacementY() const
Returns the vertical displacement for odd numbered columns in the pattern.
void setColor(const QColor &c) override
Sets the "representative" color for the symbol layer.
Qgis::RenderUnit mDistanceXUnit
void startFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called before the layer will be rendered for a particular feature.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsPointPatternFillSymbolLayer using the specified properties map containing symbol pro...
unsigned long seed() const
Returns the random number seed to use when randomly shifting points, or 0 if a truly random sequence ...
Qgis::RenderUnit mDisplacementYUnit
Qgis::MarkerClipMode clipMode() const
Returns the marker clipping mode, which defines how markers are clipped at the edges of shapes.
bool hasDataDefinedProperties() const override
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
double offsetY() const
Returns the vertical offset values for points in the pattern.
QgsSymbol * subSymbol() override
Returns the symbol's sub symbol, if present.
QgsMapUnitScale mDistanceXMapUnitScale
void setMapUnitScale(const QgsMapUnitScale &scale) override
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
QString layerType() const override
Returns a string that represents this layer type.
void applyDataDefinedSettings(QgsSymbolRenderContext &context) override
Applies data defined settings prior to generating the fill symbol brush.
Qgis::RenderUnit mRandomDeviationXUnit
Qgis::RenderUnit mOffsetXUnit
Qgis::RenderUnit mDistanceYUnit
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
QgsMapUnitScale mOffsetXMapUnitScale
void stopFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called after the layer has been rendered for a particular feature.
Qgis::RenderUnit mOffsetYUnit
QColor color() const override
Returns the "representative" color of the symbol layer.
Qgis::RenderUnit mRandomDeviationYUnit
QgsPointPatternFillSymbolLayer()
QgsMapUnitScale mRandomDeviationXMapUnitScale
void toSld(QDomDocument &doc, QDomElement &element, const QVariantMap &props) const override
Saves the symbol layer as SLD.
double offsetX() const
Returns the horizontal offset values for points in the pattern.
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
Qgis::RenderUnit mDisplacementXUnit
std::unique_ptr< QgsMarkerSymbol > mMarkerSymbol
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
QgsPointPatternFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
QgsMapUnitScale mRandomDeviationYMapUnitScale
double displacementX() const
Returns the horizontal displacement for odd numbered rows in the pattern.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
~QgsPointPatternFillSymbolLayer() override
QgsMapUnitScale mOffsetYMapUnitScale
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer's subsymbol. takes ownership of the passed symbol.
double distanceY() const
Returns the vertical distance between rendered markers in the fill.
void setClipMode(Qgis::MarkerClipMode mode)
Sets the marker clipping mode, which defines how markers are clipped at the edges of shapes.
static QgsSymbolLayer * createFromSld(QDomElement &element)
A class to represent a 2D point.
Point geometry type, with support for z-dimension and m-values.
void addInteriorRing(QgsCurve *ring) override
Adds an interior ring to the geometry (takes ownership)
static QgsProject * instance()
Returns the QgsProject singleton instance.
QgsPathResolver pathResolver() const
Returns path resolver object with considering whether the project uses absolute or relative paths and...
QVariant value(int key, const QgsExpressionContext &context, const QVariant &defaultValue=QVariant()) const override
Returns the calculated value of the property with the specified key from within the collection.
bool isActive(int key) const override
Returns true if the collection contains an active property with the specified key.
static QVariantMap propertyMapToVariantMap(const QMap< QString, QgsProperty > &propertyMap)
Convert a map of QgsProperty to a map of QVariant This is useful to save a map of properties.
static QMap< QString, QgsProperty > variantMapToPropertyMap(const QVariantMap &variantMap)
Convert a map of QVariant to a map of QgsProperty This is useful to restore a map of properties.
A fill symbol layer which places markers at random locations within polygons.
~QgsRandomMarkerFillSymbolLayer() override
int pointCount() const
Returns the count of random points to render in the fill.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
void startFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called before the layer will be rendered for a particular feature.
QgsRandomMarkerFillSymbolLayer(int pointCount=10, Qgis::PointCountMethod method=Qgis::PointCountMethod::Absolute, double densityArea=250.0, unsigned long seed=0)
Constructor for QgsRandomMarkerFillSymbolLayer, with the specified pointCount.
unsigned long seed() const
Returns the random number seed to use when generating points, or 0 if a truly random sequence will be...
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsRandomMarkerFillSymbolLayer using the specified properties map containing symbol pro...
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
QString layerType() const override
Returns a string that represents this layer type.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
QgsRandomMarkerFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
void setMapUnitScale(const QgsMapUnitScale &scale) override
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer's subsymbol. takes ownership of the passed symbol.
bool hasDataDefinedProperties() const override
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
void stopFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called after the layer has been rendered for a particular feature.
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
void setCountMethod(Qgis::PointCountMethod method)
Sets the count method used to randomly fill the polygon.
bool clipPoints() const
Returns true if point markers should be clipped to the polygon boundary.
bool canCauseArtifactsBetweenAdjacentTiles() const override
Returns true if the symbol layer rendering can cause visible artifacts across a single feature when t...
void setClipPoints(bool clipped)
Sets whether point markers should be clipped to the polygon boundary.
QgsSymbol * subSymbol() override
Returns the symbol's sub symbol, if present.
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
QColor color() const override
Returns the "representative" color of the symbol layer.
void setSeed(unsigned long seed)
Sets the random number seed to use when generating points, or 0 if a truly random sequence will be us...
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
void setPointCount(int count)
Sets the count of random points to render in the fill.
Qgis::PointCountMethod countMethod() const
Returns the count method used to randomly fill the polygon.
double densityArea() const
Returns the density area used to count the number of points to randomly fill the polygon.
void setColor(const QColor &color) override
Sets the "representative" color for the symbol layer.
void setDensityArea(double area)
Sets the density area used to count the number of points to randomly fill the polygon.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QgsMapUnitScale mapUnitScale() const override
A class for filling symbols with a repeated raster image.
void applyDataDefinedSettings(QgsSymbolRenderContext &context) override
Applies data defined settings prior to generating the fill symbol brush.
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
double width() const
Returns the width used for scaling the image used in the fill.
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
static QgsSymbolLayer * createFromSld(QDomElement &element)
Creates a new QgsRasterFillSymbolLayer from a SLD element.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsRasterFillSymbolLayer from a properties map.
QString layerType() const override
Returns a string that represents this layer type.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QgsRasterFillSymbolLayer(const QString &imageFilePath=QString())
Constructor for QgsRasterFillSymbolLayer, using a raster fill from the specified imageFilePath.
double opacity() const
Returns the opacity for the raster image used in the fill.
~QgsRasterFillSymbolLayer() override
void setOpacity(double opacity)
Sets the opacity for the raster image used in the fill.
QColor color() const override
Returns the "representative" color of the symbol layer.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
QString imageFilePath() const
The path to the raster image used for the fill.
void setImageFilePath(const QString &imagePath)
Sets the path to the raster image used for the fill.
static void resolvePaths(QVariantMap &properties, const QgsPathResolver &pathResolver, bool saving)
Turns relative paths in properties map to absolute when reading and vice versa when writing.
QPointF offset() const
Returns the offset for the fill.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer's subsymbol. takes ownership of the passed symbol.
QgsRasterFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
bool applyBrushTransformFromContext(QgsSymbolRenderContext *context=nullptr) const override
Returns true if the image brush should be transformed using the render context's texture origin.
void setCoordinateMode(Qgis::SymbolCoordinateReference mode)
Set the coordinate mode for fill.
A rectangle specified with double values.
QgsPointXY center() const
Returns the center point of the rectangle.
Contains information about the context of a rendering operation.
void setForceVectorOutput(bool force)
Sets whether rendering operations should use vector operations instead of any faster raster shortcuts...
double scaleFactor() const
Returns the scaling factor for the render to convert painter units to physical sizes.
void setScaleFactor(double factor)
Sets the scaling factor for the render to convert painter units to physical sizes.
QSet< QString > disabledSymbolLayersV2() const
When rendering a map layer in a second pass (for selective masking), some symbol layers may be disabl...
double convertToPainterUnits(double size, Qgis::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale(), Qgis::RenderSubcomponentProperty property=Qgis::RenderSubcomponentProperty::Generic) const
Converts a size from the specified units to painter units (pixels).
QPainter * painter()
Returns the destination QPainter for the render operation.
double rendererScale() const
Returns the renderer map scale.
void setPainterFlagsUsingContext(QPainter *painter=nullptr) const
Sets relevant flags on a destination painter, using the flags and settings currently defined for the ...
QgsExpressionContext & expressionContext()
Gets the expression context.
bool forceVectorOutput() const
Returns true if rendering operations should use vector operations instead of any faster raster shortc...
void setDisabledSymbolLayersV2(const QSet< QString > &symbolLayers)
When rendering a map layer in a second pass (for selective masking), some symbol layers may be disabl...
void setFlag(Qgis::RenderContextFlag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected)
const QgsMapToPixel & mapToPixel() const
Returns the context's map to pixel transform, which transforms between map coordinates and device coo...
QColor selectionColor() const
Returns the color to use when rendering selected features.
void setMapToPixel(const QgsMapToPixel &mtp)
Sets the context's map to pixel transform, which transforms between map coordinates and device coordi...
QgsFeedback * feedback() const
Returns the feedback object that can be queried regularly during rendering to check if rendering shou...
QPointF textureOrigin() const
Returns the texture origin, which should be used as a brush transform when rendering using QBrush obj...
void setPainter(QPainter *p)
Sets the destination QPainter for the render operation.
bool renderingStopped() const
Returns true if the rendering operation has been stopped and any ongoing rendering should be canceled...
static QgsRenderContext fromQPainter(QPainter *painter)
Creates a default render context given a pixel based QPainter destination.
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
void setRendererScale(double scale)
Sets the renderer map scale.
Qgis::RenderContextFlags flags() const
Returns combination of flags used for rendering.
const QgsPathResolver & pathResolver() const
Returns the path resolver for conversion between relative and absolute paths during rendering operati...
A class for filling symbols with a repeated SVG file.
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
void setParameters(const QMap< QString, QgsProperty > ¶meters)
Sets the dynamic SVG parameters.
QString svgFilePath() const
Returns the path to the SVG file used to render the fill.
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
QColor dxfColor(QgsSymbolRenderContext &context) const override
Gets color.
static QgsSymbolLayer * createFromSld(QDomElement &element)
Creates a new QgsSVGFillSymbolLayer from a SLD element.
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer's subsymbol. takes ownership of the passed symbol.
QColor svgStrokeColor() const
Returns the stroke color used for rendering the SVG content.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
Qgis::RenderUnit patternWidthUnit() const
Returns the units for the width of the SVG images in the pattern.
const QgsMapUnitScale & svgStrokeWidthMapUnitScale() const
Returns the map unit scale for the pattern's stroke.
double svgStrokeWidth() const
Returns the stroke width used for rendering the SVG content.
QString layerType() const override
Returns a string that represents this layer type.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QMap< QString, QgsProperty > parameters() const
Returns the dynamic SVG parameters.
QgsSVGFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
QgsSVGFillSymbolLayer(const QString &svgFilePath, double width=20, double rotation=0.0)
Constructor for QgsSVGFillSymbolLayer, using the SVG picture at the specified absolute file path.
void setSvgFilePath(const QString &svgPath)
Sets the path to the SVG file to render in the fill.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsSVGFillSymbolLayer from a properties map.
QColor svgFillColor() const
Returns the fill color used for rendering the SVG content.
static void resolvePaths(QVariantMap &properties, const QgsPathResolver &pathResolver, bool saving)
Turns relative paths in properties map to absolute when reading and vice versa when writing.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
const QgsMapUnitScale & patternWidthMapUnitScale() const
Returns the map unit scale for the pattern's width.
Qgis::RenderUnit svgStrokeWidthUnit() const
Returns the units for the stroke width.
double patternWidth() const
Returns the width of the rendered SVG content within the fill (i.e.
bool hasDataDefinedProperties() const override
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
~QgsSVGFillSymbolLayer() override
void setMapUnitScale(const QgsMapUnitScale &scale) override
void toSld(QDomDocument &doc, QDomElement &element, const QVariantMap &props) const override
Saves the symbol layer as SLD.
void applyDataDefinedSettings(QgsSymbolRenderContext &context) override
Applies data defined settings prior to generating the fill symbol brush.
QgsMapUnitScale mapUnitScale() const override
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
QgsSymbol * subSymbol() override
Returns the symbol's sub symbol, if present.
Scoped object for saving and restoring a QPainter object's state.
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
QgsShapeburstFillSymbolLayer(const QColor &color=DEFAULT_SIMPLEFILL_COLOR, const QColor &color2=Qt::white, Qgis::GradientColorSource colorType=Qgis::GradientColorSource::SimpleTwoColor, int blurRadius=0, bool useWholeShape=true, double maxDistance=5)
Constructor for QgsShapeburstFillSymbolLayer.
QgsShapeburstFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
~QgsShapeburstFillSymbolLayer() override
int blurRadius() const
Returns the blur radius, which controls the amount of blurring applied to the fill.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
QColor color2() const
Returns the color used for the endpoint of the shapeburst fill.
void setMapUnitScale(const QgsMapUnitScale &scale) override
QgsMapUnitScale mapUnitScale() const override
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
bool canCauseArtifactsBetweenAdjacentTiles() const override
Returns true if the symbol layer rendering can cause visible artifacts across a single feature when t...
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsShapeburstFillSymbolLayer using the specified properties map containing symbol prope...
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
QPointF offset() const
Returns the offset for the shapeburst fill.
bool useWholeShape() const
Returns whether the shapeburst fill is set to cover the entire shape.
bool ignoreRings() const
Returns whether the shapeburst fill is set to ignore polygon interior rings.
double maxDistance() const
Returns the maximum distance from the shape's boundary which is shaded.
QString layerType() const override
Returns a string that represents this layer type.
Qgis::GradientColorSource colorType() const
Returns the color mode used for the shapeburst fill.
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
void setColorRamp(QgsColorRamp *ramp)
Sets the color ramp used to draw the shapeburst fill.
QgsSimpleFillSymbolLayer(const QColor &color=DEFAULT_SIMPLEFILL_COLOR, Qt::BrushStyle style=DEFAULT_SIMPLEFILL_STYLE, const QColor &strokeColor=DEFAULT_SIMPLEFILL_BORDERCOLOR, Qt::PenStyle strokeStyle=DEFAULT_SIMPLEFILL_BORDERSTYLE, double strokeWidth=DEFAULT_SIMPLEFILL_BORDERWIDTH, Qt::PenJoinStyle penJoinStyle=DEFAULT_SIMPLEFILL_JOINSTYLE)
double dxfWidth(const QgsDxfExport &e, QgsSymbolRenderContext &context) const override
Gets line width.
Qt::PenJoinStyle penJoinStyle() const
QColor strokeColor() const override
Returns the stroke color for the symbol layer.
QColor dxfBrushColor(QgsSymbolRenderContext &context) const override
Gets brush/fill color.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
Qt::BrushStyle dxfBrushStyle() const override
Gets brush/fill style.
QString ogrFeatureStyle(double mmScaleFactor, double mapUnitScaleFactor) const override
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
Qgis::RenderUnit mOffsetUnit
~QgsSimpleFillSymbolLayer() override
void toSld(QDomDocument &doc, QDomElement &element, const QVariantMap &props) const override
Saves the symbol layer as SLD.
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
QColor dxfColor(QgsSymbolRenderContext &context) const override
Gets color.
QColor fillColor() const override
Returns the fill color for the symbol layer.
Qt::PenStyle strokeStyle() const
QString layerType() const override
Returns a string that represents this layer type.
double dxfAngle(QgsSymbolRenderContext &context) const override
Gets angle.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QgsMapUnitScale mOffsetMapUnitScale
double strokeWidth() const
Qgis::RenderUnit mStrokeWidthUnit
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
QPointF offset() const
Returns the offset by which polygons will be translated during rendering.
Qt::PenStyle dxfPenStyle() const override
Gets pen style.
QgsMapUnitScale mStrokeWidthMapUnitScale
QImage toTiledPatternImage() const override
Renders the symbol layer as an image that can be used as a seamless pattern fill for polygons,...
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
QgsSimpleFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
Qt::PenStyle mStrokeStyle
QgsMapUnitScale mapUnitScale() const override
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
Qt::PenJoinStyle mPenJoinStyle
Qt::BrushStyle mBrushStyle
void setMapUnitScale(const QgsMapUnitScale &scale) override
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsSimpleFillSymbolLayer using the specified properties map containing symbol propertie...
static QgsSymbolLayer * createFromSld(QDomElement &element)
The QgsSldExportContext class holds SLD export options and other information related to SLD export of...
QByteArray getImageData(const QString &path, bool blocking=false) const
Gets the SVG content corresponding to the given path.
QPicture svgAsPicture(const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth, double widthScaleFactor, bool forceVectorOutput=false, double fixedAspectRatio=0, bool blocking=false, const QMap< QString, QString > ¶meters=QMap< QString, QString >())
Returns an SVG drawing as a QPicture.
void containsParams(const QString &path, bool &hasFillParam, QColor &defaultFillColor, bool &hasStrokeParam, QColor &defaultStrokeColor, bool &hasStrokeWidthParam, double &defaultStrokeWidth, bool blocking=false) const
Tests if an SVG file contains parameters for fill, stroke color, stroke width.
QImage svgAsImage(const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth, double widthScaleFactor, bool &fitsInCache, double fixedAspectRatio=0, bool blocking=false, const QMap< QString, QString > ¶meters=QMap< QString, QString >())
Returns an SVG drawing as a QImage.
static bool rotationFromSldElement(QDomElement &element, QString &rotationFunc)
static Qgis::MarkerClipMode decodeMarkerClipMode(const QString &string, bool *ok=nullptr)
Decodes a string representing a marker clip mode.
static QString encodePenStyle(Qt::PenStyle style)
static Qt::PenJoinStyle decodePenJoinStyle(const QString &str)
static QString encodeMapUnitScale(const QgsMapUnitScale &mapUnitScale)
static QgsStringMap evaluatePropertiesMap(const QMap< QString, QgsProperty > &propertiesMap, const QgsExpressionContext &context)
Evaluates a map of properties using the given context and returns a variant map with evaluated expres...
static bool displacementFromSldElement(QDomElement &element, QPointF &offset)
static QColor decodeColor(const QString &str)
static QPointF polygonCentroid(const QPolygonF &points)
Calculate the centroid point of a QPolygonF.
static QString encodeBrushStyle(Qt::BrushStyle style)
static QString svgSymbolPathToName(const QString &path, const QgsPathResolver &pathResolver)
Determines an SVG symbol's name from its path.
static void externalGraphicToSld(QDomDocument &doc, QDomElement &element, const QString &path, const QString &mime, const QColor &color, double size=-1)
static QPointF polygonPointOnSurface(const QPolygonF &points, const QVector< QPolygonF > *rings=nullptr)
Calculate a point on the surface of a QPolygonF.
static QPointF toPoint(const QVariant &value, bool *ok=nullptr)
Converts a value to a point.
static void multiplyImageOpacity(QImage *image, qreal opacity)
Multiplies opacity of image pixel values with a (global) transparency value.
static QgsMapUnitScale decodeMapUnitScale(const QString &str)
static double rescaleUom(double size, Qgis::RenderUnit unit, const QVariantMap &props)
Rescales the given size based on the uomScale found in the props, if any is found,...
static QString ogrFeatureStylePen(double width, double mmScaleFactor, double mapUnitsScaleFactor, const QColor &c, Qt::PenJoinStyle joinStyle=Qt::MiterJoin, Qt::PenCapStyle capStyle=Qt::FlatCap, double offset=0.0, const QVector< qreal > *dashPattern=nullptr)
Create ogr feature style string for pen.
static bool externalGraphicFromSld(QDomElement &element, QString &path, QString &mime, QColor &color, double &size)
static void parametricSvgToSld(QDomDocument &doc, QDomElement &graphicElem, const QString &path, const QColor &fillColor, double size, const QColor &strokeColor, double strokeWidth)
Encodes a reference to a parametric SVG into SLD, as a succession of parametric SVG using URL paramet...
static bool lineFromSld(QDomElement &element, Qt::PenStyle &penStyle, QColor &color, double &width, Qt::PenJoinStyle *penJoinStyle=nullptr, Qt::PenCapStyle *penCapStyle=nullptr, QVector< qreal > *customDashPattern=nullptr, double *dashOffset=nullptr)
static QString ogrFeatureStyleBrush(const QColor &fillColr)
Create ogr feature style string for brush.
static QString encodeLineClipMode(Qgis::LineClipMode mode)
Encodes a line clip mode to a string.
static Qgis::LineClipMode decodeLineClipMode(const QString &string, bool *ok=nullptr)
Decodes a string representing a line clip mode.
static QPointF pointOnLineWithDistance(QPointF startPoint, QPointF directionPoint, double distance)
Returns a point on the line from startPoint to directionPoint that is a certain distance away from th...
static QSize tileSize(int width, int height, double &angleRad)
Calculate the minimum size in pixels of a symbol tile given the symbol width and height and the symbo...
static Qt::BrushStyle decodeBrushStyle(const QString &str)
static void lineToSld(QDomDocument &doc, QDomElement &element, Qt::PenStyle penStyle, const QColor &color, double width=-1, const Qt::PenJoinStyle *penJoinStyle=nullptr, const Qt::PenCapStyle *penCapStyle=nullptr, const QVector< qreal > *customDashPattern=nullptr, double dashOffset=0.0)
static QDomElement createVendorOptionElement(QDomDocument &doc, const QString &name, const QString &value)
static bool wellKnownMarkerFromSld(QDomElement &element, QString &name, QColor &color, QColor &strokeColor, Qt::PenStyle &strokeStyle, double &strokeWidth, double &size)
static void createDisplacementElement(QDomDocument &doc, QDomElement &element, QPointF offset)
static QString svgSymbolNameToPath(const QString &name, const QgsPathResolver &pathResolver)
Determines an SVG symbol's path from its name.
static QString encodeColor(const QColor &color)
static bool fillFromSld(QDomElement &element, Qt::BrushStyle &brushStyle, QColor &color)
static void fillToSld(QDomDocument &doc, QDomElement &element, Qt::BrushStyle brushStyle, const QColor &color=QColor())
static Qgis::RenderUnit decodeSldUom(const QString &str, double *scaleFactor=nullptr)
Decodes a SLD unit of measure string to a render unit.
static void createGeometryElement(QDomDocument &doc, QDomElement &element, const QString &geomFunc)
static double estimateMaxSymbolBleed(QgsSymbol *symbol, const QgsRenderContext &context)
Returns the maximum estimated bleed for the symbol.
static void wellKnownMarkerToSld(QDomDocument &doc, QDomElement &element, const QString &name, const QColor &color, const QColor &strokeColor, Qt::PenStyle strokeStyle, double strokeWidth=-1, double size=-1)
static Qt::PenStyle decodePenStyle(const QString &str)
static void createRotationElement(QDomDocument &doc, QDomElement &element, const QString &rotationFunc)
static Qgis::SymbolCoordinateReference decodeCoordinateReference(const QString &string, bool *ok=nullptr)
Decodes a string representing a symbol coordinate reference mode.
static QString encodePoint(QPointF point)
Encodes a QPointF to a string.
static QgsSymbolLayer * createMarkerLayerFromSld(QDomElement &element)
static QString encodePenJoinStyle(Qt::PenJoinStyle style)
static QgsStringMap getVendorOptionList(QDomElement &element)
static QPointF decodePoint(const QString &string)
Decodes a QSizeF from a string.
static QgsSymbolLayer * createLineLayerFromSld(QDomElement &element)
static QString encodeCoordinateReference(Qgis::SymbolCoordinateReference coordinateReference)
Encodes a symbol coordinate reference mode to a string.
static QString encodeMarkerClipMode(Qgis::MarkerClipMode mode)
Encodes a marker clip mode to a string.
@ PropertyGradientReference1X
Gradient reference point 1 x.
@ PropertyShapeburstIgnoreRings
Shapeburst ignore rings.
@ PropertyGradientReference2X
Gradient reference point 2 x.
@ PropertyStrokeStyle
Stroke style (eg solid, dashed)
@ PropertyDistanceX
Horizontal distance between points.
@ PropertyFile
Filename, eg for svg files.
@ PropertyGradientType
Gradient fill type.
@ PropertyAngle
Symbol angle.
@ PropertyLineClipping
Line clipping mode (since QGIS 3.24)
@ PropertyDistanceY
Vertical distance between points.
@ PropertyDisplacementX
Horizontal displacement.
@ PropertyGradientSpread
Gradient spread mode.
@ PropertyOffsetY
Vertical offset.
@ PropertyGradientReference1Y
Gradient reference point 1 y.
@ PropertyLineDistance
Distance between lines, or length of lines for hash line symbols.
@ PropertyBlurRadius
Shapeburst blur radius.
@ PropertyGradientReference2Y
Gradient reference point 2 y.
@ PropertyMarkerClipping
Marker clipping mode (since QGIS 3.24)
@ PropertyDensityArea
Density area.
@ PropertyGradientReference1IsCentroid
Gradient reference point 1 is centroid.
@ PropertyShapeburstUseWholeShape
Shapeburst use whole shape.
@ PropertyOffsetX
Horizontal offset.
@ PropertyJoinStyle
Line join style.
@ PropertyOpacity
Opacity.
@ PropertySecondaryColor
Secondary color (eg for gradient fills)
@ PropertyCoordinateMode
Gradient coordinate mode.
@ PropertyRandomOffsetY
Random offset Y (since QGIS 3.24)
@ PropertyLineAngle
Line angle, or angle of hash lines for hash line symbols.
@ PropertyShapeburstMaxDistance
Shapeburst fill from edge distance.
@ PropertyOffset
Symbol offset.
@ PropertyStrokeWidth
Stroke width.
@ PropertyFillColor
Fill color.
@ PropertyClipPoints
Whether markers should be clipped to polygon boundaries.
@ PropertyPointCount
Point count.
@ PropertyRandomSeed
Random number seed.
@ PropertyRandomOffsetX
Random offset X (since QGIS 3.24)
@ PropertyFillStyle
Fill style (eg solid, dots)
@ PropertyDisplacementY
Vertical displacement.
@ PropertyStrokeColor
Stroke color.
@ PropertyGradientReference2IsCentroid
Gradient reference point 2 is centroid.
@ PropertyWidth
Symbol width.
virtual bool setSubSymbol(QgsSymbol *symbol)
Sets layer's subsymbol. takes ownership of the passed symbol.
bool shouldRenderUsingSelectionColor(const QgsSymbolRenderContext &context) const
Returns true if the symbol layer should be rendered using the selection color from the render context...
Qgis::SymbolType type() const
virtual QColor fillColor() const
Returns the fill color for the symbol layer.
static const bool SELECTION_IS_OPAQUE
Whether styles for selected features ignore symbol alpha.
void removeMasks(QgsRenderContext &context, bool recursive)
When rendering, remove previously installed masks from context painter if recursive is true masks are...
virtual QSet< QString > usedAttributes(const QgsRenderContext &context) const
Returns the set of attributes referenced by the layer.
void copyDataDefinedProperties(QgsSymbolLayer *destLayer) const
Copies all data defined properties of this layer to another symbol layer.
void installMasks(QgsRenderContext &context, bool recursive)
When rendering, install masks on context painter if recursive is true masks are installed recursively...
virtual double estimateMaxBleed(const QgsRenderContext &context) const
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
static const bool SELECT_FILL_BORDER
Whether fill styles for selected features also highlight symbol stroke.
virtual QString layerType() const =0
Returns a string that represents this layer type.
virtual QColor color() const
Returns the "representative" color of the symbol layer.
virtual QColor strokeColor() const
Returns the stroke color for the symbol layer.
void copyPaintEffect(QgsSymbolLayer *destLayer) const
Copies paint effect of this layer to another symbol layer.
QgsPropertyCollection mDataDefinedProperties
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the symbol layer's property collection, used for data defined overrides.
static const bool SELECT_FILL_STYLE
Whether fill styles for selected features uses symbol layer style.
virtual bool hasDataDefinedProperties() const
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
const QgsFeature * feature() const
Returns the current feature being rendered.
QgsFields fields() const
Fields of the layer.
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for data defined symbology.
qreal opacity() const
Returns the opacity for the symbol.
QgsRenderContext & renderContext()
Returns a reference to the context's render context.
Abstract base class for all rendered symbols.
QColor color() const
Returns the symbol's color.
Qgis::SymbolType type() const
Returns the symbol's type.
double interval() const
Returns the interval between individual symbols.
const QgsMapUnitScale & intervalMapUnitScale() const
Returns the map unit scale for the interval between symbols.
void setInterval(double interval)
Sets the interval between individual symbols.
Qgis::RenderUnit intervalUnit() const
Returns the units for the interval between symbols.
static Q_INVOKABLE Qgis::RenderUnit decodeRenderUnit(const QString &string, bool *ok=nullptr)
Decodes a render unit from a string.
static Q_INVOKABLE QString encodeUnit(Qgis::DistanceUnit unit)
Encodes a distance unit to a string.
static bool isNull(const QVariant &variant)
Returns true if the specified variant should be considered a NULL value.
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
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
QMap< QString, QString > QgsStringMap
#define DEFAULT_SIMPLEFILL_JOINSTYLE
#define DEFAULT_SIMPLEFILL_COLOR
#define DEFAULT_SIMPLEFILL_STYLE
#define DEFAULT_SIMPLEFILL_BORDERSTYLE
#define DEFAULT_SIMPLEFILL_BORDERCOLOR
#define DEFAULT_SIMPLEFILL_BORDERWIDTH
QList< QgsSymbolLayer * > QgsSymbolLayerList
Single variable definition for use within a QgsExpressionContextScope.