47#include <QDomDocument>
50#include <QPagedPaintDevice>
53#include <QSvgRenderer>
56using namespace Qt::StringLiterals;
109void QgsSimpleFillSymbolLayer::applyDataDefinedSymbology(
QgsSymbolRenderContext &context, QBrush &brush, QPen &pen, QPen &selPen )
134 penColor.setAlphaF( context.
opacity() * penColor.alphaF() );
135 pen.setColor( penColor );
143 double width = exprVal.toDouble( &ok );
147 pen.setWidthF( width );
148 selPen.setWidthF( width );
185 if ( props.contains( u
"color"_s ) )
187 if ( props.contains( u
"style"_s ) )
189 if ( props.contains( u
"color_border"_s ) )
194 else if ( props.contains( u
"outline_color"_s ) )
198 else if ( props.contains( u
"line_color"_s ) )
203 if ( props.contains( u
"style_border"_s ) )
208 else if ( props.contains( u
"outline_style"_s ) )
212 else if ( props.contains( u
"line_style"_s ) )
216 if ( props.contains( u
"width_border"_s ) )
221 else if ( props.contains( u
"outline_width"_s ) )
223 strokeWidth = props[u
"outline_width"_s].toDouble();
225 else if ( props.contains( u
"line_width"_s ) )
229 if ( props.contains( u
"offset"_s ) )
231 if ( props.contains( u
"joinstyle"_s ) )
236 if ( props.contains( u
"border_width_unit"_s ) )
240 else if ( props.contains( u
"outline_width_unit"_s ) )
244 else if ( props.contains( u
"line_width_unit"_s ) )
248 if ( props.contains( u
"offset_unit"_s ) )
251 if ( props.contains( u
"border_width_map_unit_scale"_s ) )
253 if ( props.contains( u
"offset_map_unit_scale"_s ) )
256 sl->restoreOldDataDefinedProperties( props );
264 return u
"SimpleFill"_s;
281 selColor.setAlphaF( context.
opacity() );
340 if (
mBrush.style() == Qt::SolidPattern ||
mBrush.style() == Qt::NoBrush || !
dynamic_cast<QPagedPaintDevice *
>( p->device() ) )
352 p->setPen( Qt::NoPen );
356 p->setBrush( Qt::NoBrush );
373 map[u
"outline_width"_s] = QString::number(
mStrokeWidth );
399 toSld( doc, element, context );
408 QDomElement symbolizerElem = doc.createElement( u
"se:PolygonSymbolizer"_s );
409 if ( !props.value( u
"uom"_s, QString() ).toString().isEmpty() )
410 symbolizerElem.setAttribute( u
"uom"_s, props.value( u
"uom"_s, QString() ).toString() );
411 element.appendChild( symbolizerElem );
417 bool exportOk {
false };
421 if ( !image.isNull() )
424 QDomElement fillElem = doc.createElement( u
"se:Fill"_s );
425 symbolizerElem.appendChild( fillElem );
426 QDomElement graphicFillElem = doc.createElement( u
"se:GraphicFill"_s );
427 fillElem.appendChild( graphicFillElem );
428 QDomElement graphicElem = doc.createElement( u
"se:Graphic"_s );
429 graphicFillElem.appendChild( graphicElem );
432 QString pngPath { info.completeSuffix().isEmpty() ? context.
exportFilePath() : context.
exportFilePath().chopped( info.completeSuffix().length() ).append( u
"png"_s ) };
433 pngPath = QgsFileUtils::uniquePath( pngPath );
434 image.save( pngPath );
448 const double alpha { props.value( u
"alpha"_s, QVariant() ).toDouble( &ok ) };
454 QDomElement fillElem = doc.createElement( u
"se:Fill"_s );
455 symbolizerElem.appendChild( fillElem );
462 QDomElement strokeElem = doc.createElement( u
"se:Stroke"_s );
463 symbolizerElem.appendChild( strokeElem );
467 const double alpha { props.value( u
"alpha"_s, QVariant() ).toDouble( &ok ) };
488 symbolStyle.append(
';' );
497 Qt::BrushStyle fillStyle;
501 QDomElement fillElem = element.firstChildElement( u
"Fill"_s );
504 QDomElement strokeElem = element.firstChildElement( u
"Stroke"_s );
510 double scaleFactor = 1.0;
511 const QString uom = element.attribute( u
"uom"_s );
518 sl->setOutputUnit( sldUnitSize );
527 return penBleed + offsetBleed;
585 QPixmap pixmap( QSize( 32, 32 ) );
586 pixmap.fill( Qt::transparent );
588 painter.begin( &pixmap );
589 painter.setRenderHint( QPainter::Antialiasing );
597 std::unique_ptr< QgsSimpleFillSymbolLayer > layerClone(
clone() );
598 layerClone->setStrokeStyle( Qt::PenStyle::NoPen );
599 layerClone->drawPreviewIcon( symbolContext, pixmap.size() );
601 return pixmap.toImage();
633 bool refPoint1IsCentroid =
false;
635 bool refPoint2IsCentroid =
false;
640 if ( props.contains( u
"type"_s ) )
642 if ( props.contains( u
"coordinate_mode"_s ) )
644 if ( props.contains( u
"spread"_s ) )
646 if ( props.contains( u
"color_type"_s ) )
648 if ( props.contains( u
"gradient_color"_s ) )
653 else if ( props.contains( u
"color"_s ) )
657 if ( props.contains( u
"gradient_color2"_s ) )
662 if ( props.contains( u
"reference_point1"_s ) )
664 if ( props.contains( u
"reference_point1_iscentroid"_s ) )
665 refPoint1IsCentroid = props[u
"reference_point1_iscentroid"_s].toInt();
666 if ( props.contains( u
"reference_point2"_s ) )
668 if ( props.contains( u
"reference_point2_iscentroid"_s ) )
669 refPoint2IsCentroid = props[u
"reference_point2_iscentroid"_s].toInt();
670 if ( props.contains( u
"angle"_s ) )
671 angle = props[u
"angle"_s].toDouble();
673 if ( props.contains( u
"offset"_s ) )
677 std::unique_ptr<QgsColorRamp> gradientRamp;
690 if ( props.contains( u
"offset_unit"_s ) )
692 if ( props.contains( u
"offset_map_unit_scale"_s ) )
695 sl->setReferencePoint1IsCentroid( refPoint1IsCentroid );
697 sl->setReferencePoint2IsCentroid( refPoint2IsCentroid );
698 sl->setAngle(
angle );
700 sl->setColorRamp( gradientRamp.release() );
702 sl->restoreOldDataDefinedProperties( props );
719 return u
"GradientFill"_s;
722void QgsGradientFillSymbolLayer::applyDataDefinedSymbology(
QgsSymbolRenderContext &context,
const QPolygonF &points )
727 applyGradient( context,
mBrush,
mColor,
mColor2,
mGradientColorType,
mGradientRamp.get(),
mGradientType,
mCoordinateMode,
mGradientSpread,
mReferencePoint1,
mReferencePoint2,
mAngle );
766 if ( currentType == QObject::tr(
"linear" ) )
770 else if ( currentType == QObject::tr(
"radial" ) )
774 else if ( currentType == QObject::tr(
"conical" ) )
788 if ( currentCoordMode == QObject::tr(
"feature" ) )
792 else if ( currentCoordMode == QObject::tr(
"viewport" ) )
806 if ( currentSpread == QObject::tr(
"pad" ) )
810 else if ( currentSpread == QObject::tr(
"repeat" ) )
814 else if ( currentSpread == QObject::tr(
"reflect" ) )
861 if ( refPoint1IsCentroid || refPoint2IsCentroid )
866 QRectF bbox = points.boundingRect();
867 double centroidX = ( centroid.x() - bbox.left() ) / bbox.width();
868 double centroidY = ( centroid.y() - bbox.top() ) / bbox.height();
870 if ( refPoint1IsCentroid )
872 refPoint1X = centroidX;
873 refPoint1Y = centroidY;
875 if ( refPoint2IsCentroid )
877 refPoint2X = centroidX;
878 refPoint2Y = centroidY;
883 applyGradient( context,
mBrush,
color,
color2,
mGradientColorType,
mGradientRamp.get(),
gradientType,
coordinateMode, spread, QPointF( refPoint1X, refPoint1Y ), QPointF( refPoint2X, refPoint2Y ),
angle );
886QPointF QgsGradientFillSymbolLayer::rotateReferencePoint( QPointF refPoint,
double angle )
891 QLineF refLine = QLineF( QPointF( 0.5, 0.5 ), refPoint );
893 refLine.setAngle( refLine.angle() +
angle );
895 QPointF rotatedReferencePoint = refLine.p2();
897 if ( rotatedReferencePoint.x() > 1 )
898 rotatedReferencePoint.setX( 1 );
899 if ( rotatedReferencePoint.x() < 0 )
900 rotatedReferencePoint.setX( 0 );
901 if ( rotatedReferencePoint.y() > 1 )
902 rotatedReferencePoint.setY( 1 );
903 if ( rotatedReferencePoint.y() < 0 )
904 rotatedReferencePoint.setY( 0 );
906 return rotatedReferencePoint;
909void QgsGradientFillSymbolLayer::applyGradient(
913 const QColor &color2,
919 QPointF referencePoint1,
920 QPointF referencePoint2,
927 QColor fillColor2 =
color2;
928 fillColor2.setAlphaF( context.
opacity() * fillColor2.alphaF() );
939 gradient = QLinearGradient( rotatedReferencePoint1, rotatedReferencePoint2 );
942 gradient = QRadialGradient( rotatedReferencePoint1, QLineF( rotatedReferencePoint1, rotatedReferencePoint2 ).length() );
945 gradient = QConicalGradient( rotatedReferencePoint1, QLineF( rotatedReferencePoint1, rotatedReferencePoint2 ).
angle() );
951 gradient.setCoordinateMode( QGradient::ObjectBoundingMode );
954 gradient.setCoordinateMode( QGradient::StretchToDeviceMode );
960 gradient.setSpread( QGradient::PadSpread );
963 gradient.setSpread( QGradient::ReflectSpread );
966 gradient.setSpread( QGradient::RepeatSpread );
976 QgsGradientColorRamp *gradRamp =
static_cast<QgsGradientColorRamp *
>( gradientRamp );
983 gradient.setColorAt( 1.0, fillColor2 );
987 brush = QBrush( gradient );
994 selColor.setAlphaF( context.
opacity() );
1011 applyDataDefinedSymbology( context, points );
1015 p->setPen( Qt::NoPen );
1049 map[u
"type"_s] = QString::number(
static_cast<int>(
mGradientType ) );
1050 map[u
"coordinate_mode"_s] = QString::number(
static_cast< int >(
mCoordinateMode ) );
1051 map[u
"spread"_s] = QString::number(
static_cast< int >(
mGradientSpread ) );
1056 map[u
"angle"_s] = QString::number(
mAngle );
1081 return sl.release();
1145 if ( props.contains( u
"color_type"_s ) )
1149 if ( props.contains( u
"shapeburst_color"_s ) )
1154 else if ( props.contains( u
"color"_s ) )
1159 if ( props.contains( u
"shapeburst_color2"_s ) )
1164 else if ( props.contains( u
"gradient_color2"_s ) )
1168 if ( props.contains( u
"blur_radius"_s ) )
1170 blurRadius = props[u
"blur_radius"_s].toInt();
1172 if ( props.contains( u
"use_whole_shape"_s ) )
1176 if ( props.contains( u
"max_distance"_s ) )
1178 maxDistance = props[u
"max_distance"_s].toDouble();
1180 if ( props.contains( u
"offset"_s ) )
1186 std::unique_ptr<QgsColorRamp> gradientRamp;
1199 if ( props.contains( u
"offset_unit"_s ) )
1203 if ( props.contains( u
"distance_unit"_s ) )
1207 if ( props.contains( u
"offset_map_unit_scale"_s ) )
1211 if ( props.contains( u
"distance_map_unit_scale"_s ) )
1215 if ( props.contains( u
"ignore_rings"_s ) )
1217 sl->setIgnoreRings( props[u
"ignore_rings"_s].toInt() );
1221 sl->setColorRamp( gradientRamp.release() );
1224 sl->restoreOldDataDefinedProperties( props );
1231 return u
"ShapeburstFill"_s;
1241 if ( mGradientRamp.get() == ramp )
1244 mGradientRamp.reset( ramp );
1247void QgsShapeburstFillSymbolLayer::applyDataDefinedSymbology(
QgsSymbolRenderContext &context, QColor &color, QColor &color2,
int &blurRadius,
bool &useWholeShape,
double &maxDistance,
bool &ignoreRings )
1303 selColor.setAlphaF( context.
opacity() );
1304 mSelBrush = QBrush( selColor );
1321 if ( useSelectedColor )
1324 p->setBrush( mSelBrush );
1325 QPointF
offset = mOffset;
1360 int outputPixelMaxDist = 0;
1368 std::unique_ptr< QgsGradientColorRamp > twoColorGradientRamp;
1371 twoColorGradientRamp = std::make_unique< QgsGradientColorRamp >( color1,
color2 );
1375 p->setPen( QPen( Qt::NoPen ) );
1380 int pointsWidth =
static_cast< int >( std::round( points.boundingRect().width() ) );
1381 int pointsHeight =
static_cast< int >( std::round( points.boundingRect().height() ) );
1382 int imWidth = pointsWidth + ( sideBuffer * 2 );
1383 int imHeight = pointsHeight + ( sideBuffer * 2 );
1389 auto fillImage = std::make_unique< QImage >( imWidth, imHeight, QImage::Format_ARGB32_Premultiplied );
1390 if ( fillImage->isNull() )
1400 auto alphaImage = std::make_unique< QImage >( fillImage->width(), fillImage->height(), QImage::Format_ARGB32_Premultiplied );
1401 if ( alphaImage->isNull() )
1413 fillImage->fill( Qt::black );
1419 alphaImage->fill( Qt::transparent );
1425 QPainter imgPainter;
1426 imgPainter.begin( alphaImage.get() );
1427 imgPainter.setRenderHint( QPainter::Antialiasing,
true );
1428 imgPainter.setBrush( QBrush( Qt::white ) );
1429 imgPainter.setPen( QPen( Qt::black ) );
1430 imgPainter.translate( -points.boundingRect().left() + sideBuffer, -points.boundingRect().top() + sideBuffer );
1439 imgPainter.begin( fillImage.get() );
1442 imgPainter.drawImage( 0, 0, *alphaImage );
1449 imgPainter.setBrush( QBrush( Qt::white ) );
1450 imgPainter.setPen( QPen( Qt::black ) );
1451 imgPainter.translate( -points.boundingRect().left() + sideBuffer, -points.boundingRect().top() + sideBuffer );
1460 double *dtArray = distanceTransform( fillImage.get(), context.
renderContext() );
1479 imgPainter.begin( fillImage.get() );
1480 imgPainter.setCompositionMode( QPainter::CompositionMode_DestinationIn );
1481 imgPainter.drawImage( 0, 0, *alphaImage );
1489 QPointF
offset = mOffset;
1506 p->drawImage( points.boundingRect().left() - sideBuffer, points.boundingRect().top() - sideBuffer, *fillImage );
1517void QgsShapeburstFillSymbolLayer::distanceTransform1d(
double *f,
int n,
int *v,
double *z,
double *d )
1523 for (
int q = 1; q <= n - 1; q++ )
1525 double s = ( ( f[q] +
static_cast< double >( q ) * q ) - ( f[v[k]] + (
static_cast< double >( v[k] ) * v[k] ) ) ) / ( 2 * q - 2 * v[k] );
1529 s = ( ( f[q] +
static_cast< double >( q ) * q ) - ( f[v[k]] + (
static_cast< double >( v[k] ) * v[k] ) ) ) / ( 2 * q - 2 * v[k] );
1538 for (
int q = 0; q <= n - 1; q++ )
1540 while ( z[k + 1] < q )
1542 d[q] =
static_cast< double >( q - v[k] ) * ( q - v[k] ) + f[v[k]];
1547void QgsShapeburstFillSymbolLayer::distanceTransform2d(
double *im,
int width,
int height,
QgsRenderContext &context )
1549 int maxDimension = std::max( width, height );
1550 double *f =
new double[maxDimension];
1551 int *v =
new int[maxDimension];
1552 double *z =
new double[maxDimension + 1];
1553 double *d =
new double[maxDimension];
1556 for (
int x = 0; x < width; x++ )
1561 for (
int y = 0; y < height; y++ )
1563 f[y] = im[x +
static_cast< std::size_t
>( y ) * width];
1565 distanceTransform1d( f, height, v, z, d );
1566 for (
int y = 0; y < height; y++ )
1568 im[x +
static_cast< std::size_t
>( y ) * width] = d[y];
1573 for (
int y = 0; y < height; y++ )
1578 for (
int x = 0; x < width; x++ )
1580 f[x] = im[x +
static_cast< std::size_t
>( y ) * width];
1582 distanceTransform1d( f, width, v, z, d );
1583 for (
int x = 0; x < width; x++ )
1585 im[x +
static_cast< std::size_t
>( y ) * width] = d[x];
1596double *QgsShapeburstFillSymbolLayer::distanceTransform( QImage *im,
QgsRenderContext &context )
1598 int width = im->width();
1599 int height = im->height();
1601 double *dtArray =
new double[
static_cast< std::size_t
>( width ) * height];
1605 std::size_t idx = 0;
1606 for (
int heightIndex = 0; heightIndex < height; ++heightIndex )
1611 const QRgb *scanLine =
reinterpret_cast< const QRgb *
>( im->constScanLine( heightIndex ) );
1612 for (
int widthIndex = 0; widthIndex < width; ++widthIndex )
1614 tmpRgb = scanLine[widthIndex];
1615 if ( qRed( tmpRgb ) == 0 )
1630 distanceTransform2d( dtArray, width, height, context );
1635void QgsShapeburstFillSymbolLayer::dtArrayToQImage(
double *array, QImage *im,
QgsColorRamp *ramp,
QgsRenderContext &context,
bool useWholeShape,
int maxPixelDistance )
1637 int width = im->width();
1638 int height = im->height();
1641 double maxDistanceValue;
1646 double dtMaxValue = array[0];
1647 for ( std::size_t i = 1; i < static_cast< std::size_t >( width ) * height; ++i )
1649 if ( array[i] > dtMaxValue )
1651 dtMaxValue = array[i];
1656 maxDistanceValue = std::sqrt( dtMaxValue );
1661 maxDistanceValue = maxPixelDistance;
1665 std::size_t idx = 0;
1666 double squaredVal = 0;
1669 for (
int heightIndex = 0; heightIndex < height; ++heightIndex )
1674 QRgb *scanLine =
reinterpret_cast< QRgb *
>( im->scanLine( heightIndex ) );
1675 for (
int widthIndex = 0; widthIndex < width; ++widthIndex )
1678 squaredVal = array[idx];
1681 if ( maxDistanceValue > 0 )
1683 pixVal = squaredVal > 0 ? std::min( ( std::sqrt( squaredVal ) / maxDistanceValue ), 1.0 ) : 0;
1692 scanLine[widthIndex] = qPremultiply( ramp->
color( pixVal ).rgba() );
1703 map[u
"color_type"_s] = QString::number(
static_cast< int >( mColorType ) );
1704 map[u
"blur_radius"_s] = QString::number( mBlurRadius );
1705 map[u
"use_whole_shape"_s] = QString::number( mUseWholeShape );
1706 map[u
"max_distance"_s] = QString::number( mMaxDistance );
1709 map[u
"ignore_rings"_s] = QString::number( mIgnoreRings );
1713 if ( mGradientRamp )
1715 map.insert( mGradientRamp->properties() );
1723 auto sl = std::make_unique< QgsShapeburstFillSymbolLayer >(
mColor, mColor2, mColorType, mBlurRadius, mUseWholeShape, mMaxDistance );
1724 if ( mGradientRamp )
1726 sl->setColorRamp( mGradientRamp->clone() );
1728 sl->setDistanceUnit( mDistanceUnit );
1729 sl->setDistanceMapUnitScale( mDistanceMapUnitScale );
1730 sl->setIgnoreRings( mIgnoreRings );
1731 sl->setOffset( mOffset );
1732 sl->setOffsetUnit( mOffsetUnit );
1733 sl->setOffsetMapUnitScale( mOffsetMapUnitScale );
1735 return sl.release();
1740 double offsetBleed = context.
convertToPainterUnits( std::max( std::fabs( mOffset.x() ), std::fabs( mOffset.y() ) ), mOffsetUnit, mOffsetMapUnitScale );
1751 mDistanceUnit = unit;
1757 if ( mDistanceUnit == mOffsetUnit )
1759 return mDistanceUnit;
1774 mDistanceMapUnitScale = scale;
1775 mOffsetMapUnitScale = scale;
1780 if ( mDistanceMapUnitScale == mOffsetMapUnitScale )
1782 return mDistanceMapUnitScale;
1806 p->setPen( QPen( Qt::NoPen ) );
1808 QTransform bkTransform =
mBrush.transform();
1812 QTransform t =
mBrush.transform();
1813 t.translate( leftCorner.x(), leftCorner.y() );
1814 mBrush.setTransform( t );
1818 QTransform t =
mBrush.transform();
1819 t.translate( 0, 0 );
1820 mBrush.setTransform( t );
1824 if ( useSelectedColor )
1827 p->setBrush( QBrush( selColor ) );
1833 QTransform t =
mBrush.transform();
1835 mBrush.setTransform( t );
1840 mBrush.setTransform( bkTransform );
1876 return Qt::SolidLine;
1880 return Qt::SolidLine;
1884 return mStroke->dxfPenStyle();
1920 , mPatternWidth( width )
1924 mColor = QColor( 255, 255, 255 );
1930 , mPatternWidth( width )
1931 , mSvgData( svgData )
1936 mColor = QColor( 255, 255, 255 );
1937 setDefaultSvgParams();
1945 mPatternWidthUnit = unit;
1946 mSvgStrokeWidthUnit = unit;
1949 mStroke->setOutputUnit( unit );
1955 if ( mPatternWidthUnit != unit || mSvgStrokeWidthUnit != unit ||
mStrokeWidthUnit != unit )
1965 mPatternWidthMapUnitScale = scale;
1966 mSvgStrokeWidthMapUnitScale = scale;
1973 return mPatternWidthMapUnitScale;
1983 mSvgFilePath = svgPath;
1984 setDefaultSvgParams();
2007 std::unique_ptr< QgsSVGFillSymbolLayer > symbolLayer;
2010 symbolLayer = std::make_unique< QgsSVGFillSymbolLayer >(
svgFilePath, width,
angle );
2016 data = QByteArray::fromHex(
properties[u
"data"_s].toString().toLocal8Bit() );
2018 symbolLayer = std::make_unique< QgsSVGFillSymbolLayer >( data, width,
angle );
2022 if (
properties.contains( u
"svgFillColor"_s ) )
2027 else if (
properties.contains( u
"color"_s ) )
2031 if (
properties.contains( u
"svgOutlineColor"_s ) )
2036 else if (
properties.contains( u
"outline_color"_s ) )
2040 else if (
properties.contains( u
"line_color"_s ) )
2044 if (
properties.contains( u
"svgOutlineWidth"_s ) )
2047 symbolLayer->setSvgStrokeWidth(
properties[u
"svgOutlineWidth"_s].toDouble() );
2049 else if (
properties.contains( u
"outline_width"_s ) )
2051 symbolLayer->setSvgStrokeWidth(
properties[u
"outline_width"_s].toDouble() );
2053 else if (
properties.contains( u
"line_width"_s ) )
2055 symbolLayer->setSvgStrokeWidth(
properties[u
"line_width"_s].toDouble() );
2059 if (
properties.contains( u
"pattern_width_unit"_s ) )
2063 if (
properties.contains( u
"pattern_width_map_unit_scale"_s ) )
2067 if (
properties.contains( u
"svg_outline_width_unit"_s ) )
2071 if (
properties.contains( u
"svg_outline_width_map_unit_scale"_s ) )
2075 if (
properties.contains( u
"outline_width_unit"_s ) )
2079 if (
properties.contains( u
"outline_width_map_unit_scale"_s ) )
2084 if (
properties.contains( u
"parameters"_s ) )
2090 symbolLayer->restoreOldDataDefinedProperties(
properties );
2097 QVariantMap::iterator it =
properties.find( u
"svgFile"_s );
2109 return u
"SVGFill"_s;
2112void QgsSVGFillSymbolLayer::applyPattern(
2114 const QString &svgFilePath,
2115 double patternWidth,
2117 const QColor &svgFillColor,
2118 const QColor &svgStrokeColor,
2119 double svgStrokeWidth,
2127 if ( mSvgViewBox.isNull() )
2134 if (
static_cast< int >( size ) < 1.0 || 10000.0 < size )
2136 brush.setTextureImage( QImage() );
2140 bool fitsInCache =
true;
2147 QPicture patternPict
2150 double hwRatio = 1.0;
2151 if ( patternPict.width() > 0 )
2153 hwRatio =
static_cast< double >( patternPict.height() ) /
static_cast< double >( patternPict.width() );
2155 patternImage = QImage(
static_cast< int >( size ),
static_cast< int >( size * hwRatio ), QImage::Format_ARGB32_Premultiplied );
2156 patternImage.fill( 0 );
2158 QPainter p( &patternImage );
2159 p.drawPicture( QPointF( size / 2, size * hwRatio / 2 ), patternPict );
2162 QTransform brushTransform;
2165 QImage transparentImage = patternImage.copy();
2167 brush.setTextureImage( transparentImage );
2171 brush.setTextureImage( patternImage );
2173 brush.setTransform( brushTransform );
2181 applyPattern(
mBrush, mSvgFilePath, mPatternWidth, mPatternWidthUnit,
mColor, mSvgStrokeColor, mSvgStrokeWidth, mSvgStrokeWidthUnit, context, mPatternWidthMapUnitScale, mSvgStrokeWidthMapUnitScale, evaluatedParameters );
2205 mStroke->renderPolyline( points, context.
feature(), context.
renderContext(), -1, useSelectedColor );
2208 for (
auto ringIt = rings->constBegin(); ringIt != rings->constEnd(); ++ringIt )
2210 mStroke->renderPolyline( *ringIt, context.
feature(), context.
renderContext(), -1, useSelectedColor );
2219 if ( !mSvgFilePath.isEmpty() )
2221 map.insert( u
"svgFile"_s, mSvgFilePath );
2225 map.insert( u
"data"_s, QString( mSvgData.toHex() ) );
2228 map.insert( u
"width"_s, QString::number( mPatternWidth ) );
2229 map.insert( u
"angle"_s, QString::number(
mAngle ) );
2234 map.insert( u
"outline_width"_s, QString::number( mSvgStrokeWidth ) );
2251 std::unique_ptr< QgsSVGFillSymbolLayer > clonedLayer;
2252 if ( !mSvgFilePath.isEmpty() )
2254 clonedLayer = std::make_unique< QgsSVGFillSymbolLayer >( mSvgFilePath, mPatternWidth,
mAngle );
2255 clonedLayer->setSvgFillColor(
mColor );
2256 clonedLayer->setSvgStrokeColor( mSvgStrokeColor );
2257 clonedLayer->setSvgStrokeWidth( mSvgStrokeWidth );
2261 clonedLayer = std::make_unique< QgsSVGFillSymbolLayer >( mSvgData, mPatternWidth,
mAngle );
2264 clonedLayer->setPatternWidthUnit( mPatternWidthUnit );
2265 clonedLayer->setPatternWidthMapUnitScale( mPatternWidthMapUnitScale );
2266 clonedLayer->setSvgStrokeWidthUnit( mSvgStrokeWidthUnit );
2267 clonedLayer->setSvgStrokeWidthMapUnitScale( mSvgStrokeWidthMapUnitScale );
2271 clonedLayer->setParameters( mParameters );
2275 clonedLayer->setSubSymbol( mStroke->clone() );
2278 return clonedLayer.release();
2285 toSld( doc, element, context );
2291 QDomElement symbolizerElem = doc.createElement( u
"se:PolygonSymbolizer"_s );
2292 if ( !props.value( u
"uom"_s, QString() ).toString().isEmpty() )
2293 symbolizerElem.setAttribute( u
"uom"_s, props.value( u
"uom"_s, QString() ).toString() );
2294 element.appendChild( symbolizerElem );
2298 QDomElement fillElem = doc.createElement( u
"se:Fill"_s );
2299 symbolizerElem.appendChild( fillElem );
2301 QDomElement graphicFillElem = doc.createElement( u
"se:GraphicFill"_s );
2302 fillElem.appendChild( graphicFillElem );
2304 QDomElement graphicElem = doc.createElement( u
"se:Graphic"_s );
2305 graphicFillElem.appendChild( graphicElem );
2307 if ( !mSvgFilePath.isEmpty() )
2319 context.
pushWarning( QObject::tr(
"Exporting embedded SVG content to SLD is not supported" ) );
2325 double angle = props.value( u
"angle"_s, u
"0"_s ).toDouble( &ok );
2328 angleFunc = u
"%1 + %2"_s.arg( props.value( u
"angle"_s, u
"0"_s ).toString() ).arg(
mAngle );
2341 mStroke->toSld( doc, element, context );
2356 return mStroke.get();
2363 mStroke.reset(
nullptr );
2376 mStroke.reset( lineSymbol );
2386 if ( mStroke && mStroke->symbolLayer( 0 ) )
2388 double subLayerBleed = mStroke->symbolLayer( 0 )->estimateMaxBleed( context );
2389 return subLayerBleed;
2399 return QColor( Qt::black );
2401 return mStroke->
color();
2408 attr.unite( mStroke->usedAttributes( context ) );
2416 if ( mStroke && mStroke->hasDataDefinedProperties() )
2423 QString path, mimeType;
2425 Qt::PenStyle penStyle;
2426 double size, strokeWidth;
2428 QDomElement fillElem = element.firstChildElement( u
"Fill"_s );
2429 if ( fillElem.isNull() )
2432 QDomElement graphicFillElem = fillElem.firstChildElement( u
"GraphicFill"_s );
2433 if ( graphicFillElem.isNull() )
2436 QDomElement graphicElem = graphicFillElem.firstChildElement( u
"Graphic"_s );
2437 if ( graphicElem.isNull() )
2443 if ( mimeType !=
"image/svg+xml"_L1 )
2448 double scaleFactor = 1.0;
2449 const QString uom = element.attribute( u
"uom"_s );
2451 size = size * scaleFactor;
2452 strokeWidth = strokeWidth * scaleFactor;
2459 double d = angleFunc.toDouble( &ok );
2464 auto sl = std::make_unique< QgsSVGFillSymbolLayer >( path, size,
angle );
2465 sl->setOutputUnit( sldUnitSize );
2468 sl->setSvgStrokeWidth( strokeWidth );
2471 QDomElement strokeElem = element.firstChildElement( u
"Stroke"_s );
2472 if ( !strokeElem.isNull() )
2478 layers.append( l.release() );
2504 double width = mPatternWidth;
2510 QString svgFile = mSvgFilePath;
2529 double strokeWidth = mSvgStrokeWidth;
2537 applyPattern(
mBrush, svgFile, width, mPatternWidthUnit,
svgFillColor,
svgStrokeColor, strokeWidth, mSvgStrokeWidthUnit, context, mPatternWidthMapUnitScale, mSvgStrokeWidthMapUnitScale, evaluatedParameters );
2540void QgsSVGFillSymbolLayer::storeViewBox()
2542 if ( !mSvgData.isEmpty() )
2544 QSvgRenderer r( mSvgData );
2547 mSvgViewBox = r.viewBoxF();
2552 mSvgViewBox = QRectF();
2555void QgsSVGFillSymbolLayer::setDefaultSvgParams()
2557 if ( mSvgFilePath.isEmpty() )
2562 bool hasFillParam, hasFillOpacityParam, hasStrokeParam, hasStrokeWidthParam, hasStrokeOpacityParam;
2563 bool hasDefaultFillColor, hasDefaultFillOpacity, hasDefaultStrokeColor, hasDefaultStrokeWidth, hasDefaultStrokeOpacity;
2564 QColor defaultFillColor, defaultStrokeColor;
2565 double defaultStrokeWidth, defaultFillOpacity, defaultStrokeOpacity;
2569 hasDefaultFillColor,
2571 hasFillOpacityParam,
2572 hasDefaultFillOpacity,
2575 hasDefaultStrokeColor,
2577 hasStrokeWidthParam,
2578 hasDefaultStrokeWidth,
2580 hasStrokeOpacityParam,
2581 hasDefaultStrokeOpacity,
2582 defaultStrokeOpacity
2585 double newFillOpacity = hasFillOpacityParam ?
mColor.alphaF() : 1.0;
2586 double newStrokeOpacity = hasStrokeOpacityParam ? mSvgStrokeColor.alphaF() : 1.0;
2588 if ( hasDefaultFillColor )
2590 mColor = defaultFillColor;
2591 mColor.setAlphaF( newFillOpacity );
2593 if ( hasDefaultFillOpacity )
2595 mColor.setAlphaF( defaultFillOpacity );
2597 if ( hasDefaultStrokeColor )
2599 mSvgStrokeColor = defaultStrokeColor;
2600 mSvgStrokeColor.setAlphaF( newStrokeOpacity );
2602 if ( hasDefaultStrokeOpacity )
2604 mSvgStrokeColor.setAlphaF( defaultStrokeOpacity );
2606 if ( hasDefaultStrokeWidth )
2608 mSvgStrokeWidth = defaultStrokeWidth;
2621 mFillLineSymbol = std::make_unique<QgsLineSymbol>();
2629 mFillLineSymbol->setWidth( w );
2635 mFillLineSymbol->setColor(
c );
2641 return mFillLineSymbol ? mFillLineSymbol->color() :
mColor;
2653 mFillLineSymbol.reset( qgis::down_cast<QgsLineSymbol *>( symbol ) );
2662 return mFillLineSymbol.get();
2668 if ( mFillLineSymbol )
2669 attr.unite( mFillLineSymbol->usedAttributes( context ) );
2677 if ( mFillLineSymbol && mFillLineSymbol->hasDataDefinedProperties() )
2698 double lineAngleRad { qDegreesToRadians( mLineAngle ) };
2700 const int quadrant {
static_cast<int>( lineAngleRad / M_PI_2 ) };
2701 Q_ASSERT( quadrant >= 0 && quadrant <= 3 );
2711 lineAngleRad -= M_PI / 2;
2716 lineAngleRad -= M_PI;
2721 lineAngleRad -= M_PI + M_PI_2;
2729 QSize size {
static_cast<int>( distancePx ),
static_cast<int>( distancePx ) };
2731 if (
static_cast<int>( mLineAngle ) % 90 != 0 )
2733 size = QSize(
static_cast<int>( distancePx / std::sin( lineAngleRad ) ),
static_cast<int>( distancePx / std::cos( lineAngleRad ) ) );
2736 QPixmap pixmap( size );
2737 pixmap.fill( Qt::transparent );
2739 painter.begin( &pixmap );
2740 painter.setRenderHint( QPainter::Antialiasing );
2748 std::unique_ptr< QgsLinePatternFillSymbolLayer > layerClone(
clone() );
2749 layerClone->setOffset( 0 );
2750 layerClone->drawPreviewIcon( symbolContext, pixmap.size() );
2752 return pixmap.toImage();
2763 mDistanceUnit = unit;
2764 mLineWidthUnit = unit;
2767 if ( mFillLineSymbol )
2768 mFillLineSymbol->setOutputUnit( unit );
2794 mDistanceMapUnitScale = scale;
2795 mLineWidthMapUnitScale = scale;
2796 mOffsetMapUnitScale = scale;
2803 return mDistanceMapUnitScale;
2810 auto patternLayer = std::make_unique< QgsLinePatternFillSymbolLayer >();
2816 QColor
color( Qt::black );
2824 else if (
properties.contains( u
"angle"_s ) )
2828 patternLayer->setLineAngle(
lineAngle );
2834 patternLayer->setDistance(
distance );
2841 else if (
properties.contains( u
"outline_width"_s ) )
2845 else if (
properties.contains( u
"line_width"_s ) )
2849 patternLayer->setLineWidth(
lineWidth );
2855 else if (
properties.contains( u
"outline_color"_s ) )
2859 else if (
properties.contains( u
"line_color"_s ) )
2863 patternLayer->setColor(
color );
2869 patternLayer->setOffset(
offset );
2872 if (
properties.contains( u
"distance_unit"_s ) )
2876 if (
properties.contains( u
"distance_map_unit_scale"_s ) )
2880 if (
properties.contains( u
"line_width_unit"_s ) )
2884 else if (
properties.contains( u
"outline_width_unit"_s ) )
2888 if (
properties.contains( u
"line_width_map_unit_scale"_s ) )
2892 if (
properties.contains( u
"offset_unit"_s ) )
2896 if (
properties.contains( u
"offset_map_unit_scale"_s ) )
2900 if (
properties.contains( u
"outline_width_unit"_s ) )
2904 if (
properties.contains( u
"outline_width_map_unit_scale"_s ) )
2908 if (
properties.contains( u
"coordinate_reference"_s ) )
2917 patternLayer->restoreOldDataDefinedProperties(
properties );
2919 return patternLayer;
2924 return u
"LinePatternFill"_s;
2927bool QgsLinePatternFillSymbolLayer::applyPattern(
const QgsSymbolRenderContext &context, QBrush &brush,
double lineAngle,
double distance )
2929 mBrush.setTextureImage( QImage() );
2931 if ( !mFillLineSymbol )
2936 std::unique_ptr< QgsLineSymbol > fillLineSymbol( mFillLineSymbol->clone() );
2937 if ( !fillLineSymbol )
2952 outputPixelOffset = std::fmod( outputPixelOffset, outputPixelDist );
2953 if ( outputPixelOffset > outputPixelDist / 2.0 )
2954 outputPixelOffset -= outputPixelDist;
2958 double outputPixelBleed = 0;
2959 double outputPixelInterval = 0;
2960 for (
int i = 0; i < fillLineSymbol->symbolLayerCount(); i++ )
2964 outputPixelBleed = std::max( outputPixelBleed, outputPixelLayerBleed );
2966 QgsMarkerLineSymbolLayer *markerLineLayer =
dynamic_cast<QgsMarkerLineSymbolLayer *
>( layer );
2967 if ( markerLineLayer )
2976 outputPixelInterval = std::max( outputPixelInterval, outputPixelLayerInterval );
2980 if ( outputPixelInterval > 0 )
2984 double intervalScale = std::round( outputPixelInterval ) / outputPixelInterval;
2985 outputPixelInterval = std::round( outputPixelInterval );
2987 for (
int i = 0; i < fillLineSymbol->symbolLayerCount(); i++ )
2991 QgsMarkerLineSymbolLayer *markerLineLayer =
dynamic_cast<QgsMarkerLineSymbolLayer *
>( layer );
2992 if ( markerLineLayer )
3006 height = outputPixelDist;
3007 width = outputPixelInterval > 0 ? outputPixelInterval : height;
3011 width = outputPixelDist;
3012 height = outputPixelInterval > 0 ? outputPixelInterval : width;
3016 height = outputPixelDist / std::cos(
lineAngle * M_PI / 180 );
3017 width = outputPixelDist / std::sin(
lineAngle * M_PI / 180 );
3020 lineAngle = 180 * std::atan2(
static_cast< double >( height ),
static_cast< double >( width ) ) / M_PI;
3026 height = std::abs( height );
3027 width = std::abs( width );
3029 outputPixelDist = std::abs( height * std::cos(
lineAngle * M_PI / 180 ) );
3033 int offsetHeight =
static_cast< int >( std::round( outputPixelOffset / std::cos(
lineAngle * M_PI / 180 ) ) );
3034 outputPixelOffset = offsetHeight * std::cos(
lineAngle * M_PI / 180 );
3043 int bufferMulti =
static_cast< int >( std::max( std::ceil( outputPixelBleed / width ), std::ceil( outputPixelBleed / width ) ) );
3047 bufferMulti = std::max( bufferMulti, 1 );
3049 int xBuffer = width * bufferMulti;
3050 int yBuffer = height * bufferMulti;
3051 int innerWidth = width;
3052 int innerHeight = height;
3053 width += 2 * xBuffer;
3054 height += 2 * yBuffer;
3057 if ( width > 2000 || height > 2000 || width == 0 || height == 0 )
3062 QImage patternImage( width, height, QImage::Format_ARGB32 );
3063 patternImage.fill( 0 );
3065 QPointF p1, p2, p3, p4, p5, p6;
3068 p1 = QPointF( 0, yBuffer );
3069 p2 = QPointF( width, yBuffer );
3070 p3 = QPointF( 0, yBuffer + innerHeight );
3071 p4 = QPointF( width, yBuffer + innerHeight );
3075 p1 = QPointF( xBuffer, height );
3076 p2 = QPointF( xBuffer, 0 );
3077 p3 = QPointF( xBuffer + innerWidth, height );
3078 p4 = QPointF( xBuffer + innerWidth, 0 );
3082 dx = outputPixelDist * std::cos( ( 90 -
lineAngle ) * M_PI / 180.0 );
3083 dy = outputPixelDist * std::sin( ( 90 -
lineAngle ) * M_PI / 180.0 );
3084 p1 = QPointF( 0, height );
3085 p2 = QPointF( width, 0 );
3086 p3 = QPointF( -dx, height - dy );
3087 p4 = QPointF( width - dx, -dy );
3088 p5 = QPointF( dx, height + dy );
3089 p6 = QPointF( width + dx, dy );
3093 dx = outputPixelDist * std::cos( ( 90 -
lineAngle ) * M_PI / 180.0 );
3094 dy = outputPixelDist * std::sin( ( 90 -
lineAngle ) * M_PI / 180.0 );
3095 p1 = QPointF( width, 0 );
3096 p2 = QPointF( 0, height );
3097 p3 = QPointF( width - dx, -dy );
3098 p4 = QPointF( -dx, height - dy );
3099 p5 = QPointF( width + dx, dy );
3100 p6 = QPointF( dx, height + dy );
3104 dy = outputPixelDist * std::cos( ( 180 -
lineAngle ) * M_PI / 180 );
3105 dx = outputPixelDist * std::sin( ( 180 -
lineAngle ) * M_PI / 180 );
3106 p1 = QPointF( 0, 0 );
3107 p2 = QPointF( width, height );
3108 p5 = QPointF( dx, -dy );
3109 p6 = QPointF( width + dx, height - dy );
3110 p3 = QPointF( -dx, dy );
3111 p4 = QPointF( width - dx, height + dy );
3115 dy = outputPixelDist * std::cos( ( 180 -
lineAngle ) * M_PI / 180 );
3116 dx = outputPixelDist * std::sin( ( 180 -
lineAngle ) * M_PI / 180 );
3117 p1 = QPointF( width, height );
3118 p2 = QPointF( 0, 0 );
3119 p5 = QPointF( width + dx, height - dy );
3120 p6 = QPointF( dx, -dy );
3121 p3 = QPointF( width - dx, height + dy );
3122 p4 = QPointF( -dx, dy );
3129 p3 = QPointF( tempPt.x(), tempPt.y() );
3131 p4 = QPointF( tempPt.x(), tempPt.y() );
3133 p5 = QPointF( tempPt.x(), tempPt.y() );
3135 p6 = QPointF( tempPt.x(), tempPt.y() );
3139 p1 = QPointF( tempPt.x(), tempPt.y() );
3141 p2 = QPointF( tempPt.x(), tempPt.y() );
3144 QPainter p( &patternImage );
3148 p.setRenderHint( QPainter::Antialiasing,
false );
3149 QPen pen( QColor( Qt::black ) );
3150 pen.setWidthF( 0.1 );
3151 pen.setCapStyle( Qt::FlatCap );
3156 QPolygon polygon = QPolygon() << QPoint( 0, 0 ) << QPoint( width - 1, 0 ) << QPoint( width - 1, height - 1 ) << QPoint( 0, height - 1 ) << QPoint( 0, 0 );
3157 p.drawPolygon( polygon );
3159 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 );
3160 p.drawPolygon( polygon );
3166 p.setRenderHint( QPainter::Antialiasing,
true );
3169 QgsRenderContext lineRenderContext;
3179 fillLineSymbol->startRender( lineRenderContext, context.
fields() );
3181 QVector<QPolygonF> polygons;
3182 polygons.append( QPolygonF() << p1 << p2 );
3183 polygons.append( QPolygonF() << p3 << p4 );
3186 polygons.append( QPolygonF() << p5 << p6 );
3190 for (
const QPolygonF &polygon : std::as_const( polygons ) )
3192 fillLineSymbol->renderPolyline( polygon, context.
feature(), lineRenderContext, -1, useSelectedColor );
3195 fillLineSymbol->stopRender( lineRenderContext );
3199 patternImage = patternImage.copy( xBuffer, yBuffer, patternImage.width() - 2 * xBuffer, patternImage.height() - 2 * yBuffer );
3204 QImage transparentImage = patternImage.copy();
3206 brush.setTextureImage( transparentImage );
3210 brush.setTextureImage( patternImage );
3213 QTransform brushTransform;
3214 brush.setTransform( brushTransform );
3224 || ( mFillLineSymbol && mFillLineSymbol->hasDataDefinedProperties() )
3228 if ( !mRenderUsingLines )
3232 mRenderUsingLines = !applyPattern( context,
mBrush, mLineAngle, mDistance );
3235 if ( mRenderUsingLines && mFillLineSymbol )
3239 mFillLineSymbolRenderStarted =
true;
3245 if ( mFillLineSymbolRenderStarted )
3248 mFillLineSymbolRenderStarted =
false;
3255 if ( !useSelectedColor && !mRenderUsingLines )
3262 if ( !mFillLineSymbol )
3265 if ( !mFillLineSymbolRenderStarted )
3269 mFillLineSymbolRenderStarted =
true;
3299 outputPixelOffset = std::fmod( outputPixelOffset, outputPixelDistance );
3300 if ( outputPixelOffset > outputPixelDistance / 2.0 )
3301 outputPixelOffset -= outputPixelDistance;
3303 p->setPen( QPen( Qt::NoPen ) );
3328 std::unique_ptr< QgsPolygon > shapePolygon;
3329 std::unique_ptr< QgsGeometryEngine > shapeEngine;
3337 shapePolygon = std::make_unique< QgsPolygon >();
3339 shapePolygon->setExteriorRing( fromPolygon.release() );
3342 for (
const QPolygonF &ring : *rings )
3345 shapePolygon->addInteriorRing( fromRing.release() );
3349 shapeEngine->prepareGeometry();
3356 path.addPolygon( points );
3359 for (
const QPolygonF &ring : *rings )
3361 path.addPolygon( ring );
3364 p->setClipPath( path, Qt::IntersectClip );
3370 const QRectF boundingRect = points.boundingRect();
3372 QTransform invertedRotateTransform;
3378 QTransform transform;
3379 if ( applyBrushTransform )
3382 transform.translate( -boundingRect.center().x(), -boundingRect.center().y() );
3384 transform.translate( boundingRect.center().x(), boundingRect.center().y() );
3392 const QRectF transformedBounds = transform.map( points ).boundingRect();
3396 left = transformedBounds.left() - buffer * 2;
3397 top = transformedBounds.top() - buffer * 2;
3398 right = transformedBounds.right() + buffer * 2;
3399 bottom = transformedBounds.bottom() + buffer * 2;
3400 invertedRotateTransform = transform.inverted();
3402 if ( !applyBrushTransform )
3404 top -= transformedBounds.top() - ( outputPixelDistance * std::floor( transformedBounds.top() / outputPixelDistance ) );
3409 const bool needsExpressionContext = mFillLineSymbol->hasDataDefinedProperties();
3414 int currentLine = 0;
3415 for (
double currentY = top; currentY <= bottom; currentY += outputPixelDistance )
3420 if ( needsExpressionContext )
3424 double y1 = currentY;
3426 double y2 = currentY;
3427 invertedRotateTransform.map( left, currentY - outputPixelOffset, &x1, &y1 );
3428 invertedRotateTransform.map( right, currentY - outputPixelOffset, &x2, &y2 );
3434 for (
auto it = intersection->const_parts_begin(); it != intersection->const_parts_end(); ++it )
3444 mFillLineSymbol->renderPolyline( QPolygonF() << QPointF( x1, y1 ) << QPointF( x2, y2 ), context.
feature(), context.
renderContext(), -1, useSelectedColor );
3454 map.insert( u
"angle"_s, QString::number( mLineAngle ) );
3455 map.insert( u
"distance"_s, QString::number( mDistance ) );
3456 map.insert( u
"line_width"_s, QString::number( mLineWidth ) );
3458 map.insert( u
"offset"_s, QString::number( mOffset ) );
3474 if ( mFillLineSymbol )
3476 clonedLayer->setSubSymbol( mFillLineSymbol->clone() );
3479 return clonedLayer.release();
3486 toSld( doc, element, context );
3492 QDomElement symbolizerElem = doc.createElement( u
"se:PolygonSymbolizer"_s );
3493 if ( !props.value( u
"uom"_s, QString() ).toString().isEmpty() )
3494 symbolizerElem.setAttribute( u
"uom"_s, props.value( u
"uom"_s, QString() ).toString() );
3495 element.appendChild( symbolizerElem );
3500 QDomElement fillElem = doc.createElement( u
"se:Fill"_s );
3501 symbolizerElem.appendChild( fillElem );
3503 QDomElement graphicFillElem = doc.createElement( u
"se:GraphicFill"_s );
3504 fillElem.appendChild( graphicFillElem );
3506 QDomElement graphicElem = doc.createElement( u
"se:Graphic"_s );
3507 graphicFillElem.appendChild( graphicElem );
3510 bool exportOk {
false };
3514 if ( !image.isNull() )
3517 QString pngPath { info.completeSuffix().isEmpty() ? context.
exportFilePath() : context.
exportFilePath().chopped( info.completeSuffix().length() ).append( u
"png"_s ) };
3518 pngPath = QgsFileUtils::uniquePath( pngPath );
3519 image.save( pngPath );
3528 QColor lineColor = mFillLineSymbol ? mFillLineSymbol->color() : QColor();
3529 double lineWidth = mFillLineSymbol ? mFillLineSymbol->width() : 0.0;
3537 double angle = props.value( u
"angle"_s, u
"0"_s ).toDouble( &ok );
3540 angleFunc = u
"%1 + %2"_s.arg( props.value( u
"angle"_s, u
"0"_s ).toString() ).arg( mLineAngle );
3544 angleFunc = QString::number(
angle + mLineAngle );
3549 QPointF lineOffset( std::sin( mLineAngle ) * mOffset, std::cos( mLineAngle ) * mOffset );
3558 QString featureStyle;
3559 featureStyle.append(
"Brush(" );
3560 featureStyle.append( u
"fc:%1"_s.arg(
mColor.name() ) );
3561 featureStyle.append( u
",bc:%1"_s.arg(
"#00000000"_L1 ) );
3562 featureStyle.append(
",id:\"ogr-brush-2\"" );
3563 featureStyle.append( u
",a:%1"_s.arg( mLineAngle ) );
3564 featureStyle.append( u
",s:%1"_s.arg( mLineWidth * widthScaleFactor ) );
3565 featureStyle.append(
",dx:0mm" );
3566 featureStyle.append( u
",dy:%1mm"_s.arg( mDistance * widthScaleFactor ) );
3567 featureStyle.append(
')' );
3568 return featureStyle;
3575 && ( !mFillLineSymbol || !mFillLineSymbol->hasDataDefinedProperties() ) )
3600 Qt::PenStyle lineStyle;
3602 QDomElement fillElem = element.firstChildElement( u
"Fill"_s );
3603 if ( fillElem.isNull() )
3606 QDomElement graphicFillElem = fillElem.firstChildElement( u
"GraphicFill"_s );
3607 if ( graphicFillElem.isNull() )
3610 QDomElement graphicElem = graphicFillElem.firstChildElement( u
"Graphic"_s );
3611 if ( graphicElem.isNull() )
3617 if ( name !=
"horline"_L1 )
3625 double d = angleFunc.toDouble( &ok );
3634 offset = std::sqrt( std::pow( vectOffset.x(), 2 ) + std::pow( vectOffset.y(), 2 ) );
3637 double scaleFactor = 1.0;
3638 const QString uom = element.attribute( u
"uom"_s );
3640 size = size * scaleFactor;
3643 auto sl = std::make_unique< QgsLinePatternFillSymbolLayer >();
3644 sl->setOutputUnit( sldUnitSize );
3645 sl->setColor( lineColor );
3647 sl->setLineAngle(
angle );
3649 sl->setDistance( size );
3652 QDomElement strokeElem = element.firstChildElement( u
"Stroke"_s );
3653 if ( !strokeElem.isNull() )
3659 layers.append( l.release() );
3772 auto layer = std::make_unique< QgsPointPatternFillSymbolLayer >();
3773 if (
properties.contains( u
"distance_x"_s ) )
3775 layer->setDistanceX(
properties[u
"distance_x"_s].toDouble() );
3777 if (
properties.contains( u
"distance_y"_s ) )
3779 layer->setDistanceY(
properties[u
"distance_y"_s].toDouble() );
3781 if (
properties.contains( u
"displacement_x"_s ) )
3783 layer->setDisplacementX(
properties[u
"displacement_x"_s].toDouble() );
3785 if (
properties.contains( u
"displacement_y"_s ) )
3787 layer->setDisplacementY(
properties[u
"displacement_y"_s].toDouble() );
3791 layer->setOffsetX(
properties[u
"offset_x"_s].toDouble() );
3795 layer->setOffsetY(
properties[u
"offset_y"_s].toDouble() );
3798 if (
properties.contains( u
"distance_x_unit"_s ) )
3802 if (
properties.contains( u
"distance_x_map_unit_scale"_s ) )
3806 if (
properties.contains( u
"distance_y_unit"_s ) )
3810 if (
properties.contains( u
"distance_y_map_unit_scale"_s ) )
3814 if (
properties.contains( u
"displacement_x_unit"_s ) )
3818 if (
properties.contains( u
"displacement_x_map_unit_scale"_s ) )
3822 if (
properties.contains( u
"displacement_y_unit"_s ) )
3826 if (
properties.contains( u
"displacement_y_map_unit_scale"_s ) )
3830 if (
properties.contains( u
"offset_x_unit"_s ) )
3834 if (
properties.contains( u
"offset_x_map_unit_scale"_s ) )
3838 if (
properties.contains( u
"offset_y_unit"_s ) )
3842 if (
properties.contains( u
"offset_y_map_unit_scale"_s ) )
3847 if (
properties.contains( u
"random_deviation_x"_s ) )
3849 layer->setMaximumRandomDeviationX(
properties[u
"random_deviation_x"_s].toDouble() );
3851 if (
properties.contains( u
"random_deviation_y"_s ) )
3853 layer->setMaximumRandomDeviationY(
properties[u
"random_deviation_y"_s].toDouble() );
3855 if (
properties.contains( u
"random_deviation_x_unit"_s ) )
3859 if (
properties.contains( u
"random_deviation_x_map_unit_scale"_s ) )
3863 if (
properties.contains( u
"random_deviation_y_unit"_s ) )
3867 if (
properties.contains( u
"random_deviation_y_map_unit_scale"_s ) )
3871 unsigned long seed = 0;
3878 std::random_device rd;
3879 std::mt19937 mt(
static_cast< int >( rd() ) );
3880 std::uniform_int_distribution<> uniformDist( 1, 999999999 );
3881 seed = uniformDist( mt );
3883 layer->setSeed(
seed );
3885 if (
properties.contains( u
"outline_width_unit"_s ) )
3889 if (
properties.contains( u
"outline_width_map_unit_scale"_s ) )
3897 if (
properties.contains( u
"coordinate_reference"_s ) )
3904 layer->setAngle(
properties[u
"angle"_s].toDouble() );
3914 return u
"PointPatternFill"_s;
3917bool QgsPointPatternFillSymbolLayer::applyPattern(
3918 const QgsSymbolRenderContext &context, QBrush &brush,
double distanceX,
double distanceY,
double displacementX,
double displacementY,
double offsetX,
double offsetY
3929 if ( width > 2000 || height > 2000 )
3931 brush.setTextureImage( QImage() );
3935 QImage patternImage( width, height, QImage::Format_ARGB32 );
3936 patternImage.fill( 0 );
3937 if ( patternImage.isNull() )
3939 brush.setTextureImage( QImage() );
3944 QPainter p( &patternImage );
3947 QgsRenderContext pointRenderContext;
3962 for (
double currentX = -width; currentX <= width * 2.0; currentX += width )
3964 for (
double currentY = -height; currentY <= height * 2.0; currentY += height )
3966 mMarkerSymbol->renderPoint( QPointF( currentX + widthOffset, currentY + heightOffset ), context.
feature(), pointRenderContext );
3975 for (
double currentX = -width; currentX <= width * 2.0; currentX += width )
3977 for (
double currentY = -height / 2.0; currentY <= height * 2.0; currentY += height )
3979 mMarkerSymbol->renderPoint( QPointF( currentX + widthOffset + displacementPixelX, currentY + heightOffset ), context.
feature(), pointRenderContext );
3983 for (
double currentX = -width / 2.0; currentX <= width * 2.0; currentX += width )
3985 for (
double currentY = -height; currentY <= height * 2.0; currentY += height / 2.0 )
3987 mMarkerSymbol->renderPoint( QPointF( currentX + widthOffset + ( std::fmod( currentY, height ) != 0 ? displacementPixelX : 0 ), currentY + heightOffset - displacementPixelY ), context.
feature(), pointRenderContext );
3996 QImage transparentImage = patternImage.copy();
3998 brush.setTextureImage( transparentImage );
4002 brush.setTextureImage( patternImage );
4004 QTransform brushTransform;
4005 brush.setTransform( brushTransform );
4025 if ( !mRenderUsingMarkers )
4070 if ( !useSelectedColor && !mRenderUsingMarkers )
4120 const double widthOffset
4129 const double heightOffset
4150 p->setPen( QPen( Qt::NoPen ) );
4176 std::unique_ptr< QgsPolygon > shapePolygon;
4177 std::unique_ptr< QgsGeometryEngine > shapeEngine;
4184 shapePolygon = std::make_unique< QgsPolygon >();
4186 shapePolygon->setExteriorRing( fromPolygon.release() );
4189 for (
const QPolygonF &ring : *rings )
4192 shapePolygon->addInteriorRing( fromRing.release() );
4196 shapeEngine->prepareGeometry();
4203 path.addPolygon( points );
4206 for (
const QPolygonF &ring : *rings )
4208 path.addPolygon( ring );
4211 p->setClipPath( path, Qt::IntersectClip );
4217 const QRectF boundingRect = points.boundingRect();
4219 QTransform invertedRotateTransform;
4227 QTransform transform;
4228 if ( applyBrushTransform )
4231 transform.translate( -boundingRect.center().x(), -boundingRect.center().y() );
4232 transform.rotate( -
angle );
4233 transform.translate( boundingRect.center().x(), boundingRect.center().y() );
4238 transform.rotate( -
angle );
4241 const QRectF transformedBounds = transform.map( points ).boundingRect();
4242 left = transformedBounds.left() - 2 * width;
4243 top = transformedBounds.top() - 2 * height;
4244 right = transformedBounds.right() + 2 * width;
4245 bottom = transformedBounds.bottom() + 2 * height;
4246 invertedRotateTransform = transform.inverted();
4248 if ( !applyBrushTransform )
4250 left -= transformedBounds.left() - ( width * std::floor( transformedBounds.left() / width ) );
4251 top -= transformedBounds.top() - ( height * std::floor( transformedBounds.top() / height ) );
4256 left = boundingRect.left() - 2 * width;
4257 top = boundingRect.top() - 2 * height;
4258 right = boundingRect.right() + 2 * width;
4259 bottom = boundingRect.bottom() + 2 * height;
4261 if ( !applyBrushTransform )
4263 left -= boundingRect.left() - ( width * std::floor( boundingRect.left() / width ) );
4264 top -= boundingRect.top() - ( height * std::floor( boundingRect.top() / height ) );
4282 ? ( maxRandomDeviationX * width / 100 )
4292 ? ( maxRandomDeviationY * height / 100 )
4295 std::random_device rd;
4296 std::mt19937 mt(
seed == 0 ? rd() :
seed );
4297 std::uniform_real_distribution<> uniformDist( 0, 1 );
4303 const bool needsExpressionContext =
mMarkerSymbol->hasDataDefinedProperties();
4311 bool alternateColumn =
false;
4312 int currentCol = -3;
4313 for (
double currentX = left; currentX <= right; currentX += width, alternateColumn = !alternateColumn )
4318 if ( needsExpressionContext )
4321 bool alternateRow =
false;
4322 const double columnX = currentX + widthOffset;
4323 int currentRow = -3;
4324 for (
double currentY = top; currentY <= bottom; currentY += height, alternateRow = !alternateRow )
4329 double y = currentY + heightOffset;
4332 x += displacementPixelX;
4334 if ( !alternateColumn )
4335 y -= displacementPixelY;
4341 invertedRotateTransform.map( xx, yy, &x, &y );
4344 if ( useRandomShift )
4346 x += ( 2 * uniformDist( mt ) - 1 ) * maxRandomDeviationPixelX;
4347 y += ( 2 * uniformDist( mt ) - 1 ) * maxRandomDeviationPixelY;
4350 if ( needsExpressionContext )
4358 bool renderPoint =
true;
4366 renderPoint = shapeEngine->intersects( &p );
4378 renderPoint = shapeEngine->contains( markerBounds.
constGet() );
4380 renderPoint = shapeEngine->intersects( markerBounds.
constGet() );
4404 map.insert( u
"distance_x"_s, QString::number(
mDistanceX ) );
4405 map.insert( u
"distance_y"_s, QString::number(
mDistanceY ) );
4406 map.insert( u
"displacement_x"_s, QString::number(
mDisplacementX ) );
4407 map.insert( u
"displacement_y"_s, QString::number(
mDisplacementY ) );
4408 map.insert( u
"offset_x"_s, QString::number(
mOffsetX ) );
4409 map.insert( u
"offset_y"_s, QString::number(
mOffsetY ) );
4431 map.insert( u
"seed"_s, QString::number(
mSeed ) );
4432 map.insert( u
"angle"_s,
mAngle );
4443 clonedLayer->setClipMode( mClipMode );
4445 return clonedLayer.release();
4452 toSld( doc, element, context );
4458 for (
int symbolLayerIdx = 0; symbolLayerIdx <
mMarkerSymbol->symbolLayerCount(); symbolLayerIdx++ )
4460 QDomElement symbolizerElem = doc.createElement( u
"se:PolygonSymbolizer"_s );
4461 if ( !props.value( u
"uom"_s, QString() ).toString().isEmpty() )
4462 symbolizerElem.setAttribute( u
"uom"_s, props.value( u
"uom"_s, QString() ).toString() );
4463 element.appendChild( symbolizerElem );
4468 QDomElement fillElem = doc.createElement( u
"se:Fill"_s );
4469 symbolizerElem.appendChild( fillElem );
4471 QDomElement graphicFillElem = doc.createElement( u
"se:GraphicFill"_s );
4472 fillElem.appendChild( graphicFillElem );
4477 bool exportOk {
false };
4481 if ( !image.isNull() )
4483 QDomElement graphicElem = doc.createElement( u
"se:Graphic"_s );
4484 graphicFillElem.appendChild( graphicElem );
4486 QString pngPath { info.completeSuffix().isEmpty() ? context.
exportFilePath() : context.
exportFilePath().chopped( info.completeSuffix().length() ).append( u
"png"_s ) };
4487 pngPath = QgsFileUtils::uniquePath( pngPath );
4488 image.save( pngPath );
4507 symbolizerElem.appendChild( graphicMarginElem );
4511 markerLayer->writeSldMarker( doc, graphicFillElem, context );
4519 QgsDebugError( u
"Missing point pattern symbol layer. Skip it."_s );
4528 double angleRads { qDegreesToRadians(
mAngle ) };
4537 if ( displacementXPx != 0 )
4542 if ( displacementYPx != 0 )
4549 QPixmap pixmap( size );
4550 pixmap.fill( Qt::transparent );
4552 painter.begin( &pixmap );
4553 painter.setRenderHint( QPainter::Antialiasing );
4561 std::unique_ptr< QgsPointPatternFillSymbolLayer > layerClone(
clone() );
4563 layerClone->setAngle( qRadiansToDegrees( angleRads ) );
4566 layerClone->setMaximumRandomDeviationX( 0 );
4567 layerClone->setMaximumRandomDeviationY( 0 );
4569 layerClone->drawPreviewIcon( symbolContext, pixmap.size() );
4571 return pixmap.toImage();
4578 QDomElement fillElem = element.firstChildElement( u
"Fill"_s );
4579 if ( fillElem.isNull() )
4582 QDomElement graphicFillElem = fillElem.firstChildElement( u
"GraphicFill"_s );
4583 if ( graphicFillElem.isNull() )
4586 QDomElement graphicElem = graphicFillElem.firstChildElement( u
"Graphic"_s );
4587 if ( graphicElem.isNull() )
4591 if ( !simpleMarkerSl )
4595 layers.append( simpleMarkerSl.release() );
4597 auto marker = std::make_unique< QgsMarkerSymbol >( layers );
4600 const double markerSize { marker->size() };
4602 auto pointPatternFillSl = std::make_unique< QgsPointPatternFillSymbolLayer >();
4603 pointPatternFillSl->setSubSymbol( marker.release() );
4608 auto distanceParser = [&](
const QStringList &values ) {
4609 switch ( values.count() )
4614 const double v { values.at( 0 ).toDouble( &ok ) };
4617 pointPatternFillSl->setDistanceX( v * 2 + markerSize );
4618 pointPatternFillSl->setDistanceY( v * 2 + markerSize );
4625 const double vX { values.at( 1 ).toDouble( &ok ) };
4628 pointPatternFillSl->setDistanceX( vX * 2 + markerSize );
4630 const double vY { values.at( 0 ).toDouble( &ok ) };
4633 pointPatternFillSl->setDistanceY( vY * 2 + markerSize );
4640 const double vX { values.at( 1 ).toDouble( &ok ) };
4643 pointPatternFillSl->setDistanceX( vX * 2 + markerSize );
4645 const double vYt { values.at( 0 ).toDouble( &ok ) };
4648 const double vYb { values.at( 2 ).toDouble( &ok ) };
4651 pointPatternFillSl->setDistanceY( ( vYt + vYb ) + markerSize );
4659 const double vYt { values.at( 0 ).toDouble( &ok ) };
4662 const double vYb { values.at( 2 ).toDouble( &ok ) };
4665 pointPatternFillSl->setDistanceY( ( vYt + vYb ) + markerSize );
4668 const double vXr { values.at( 1 ).toDouble( &ok ) };
4671 const double vXl { values.at( 3 ).toDouble( &ok ) };
4674 pointPatternFillSl->setDistanceX( ( vXr + vXl ) + markerSize );
4685 bool distanceFromVendorOption {
false };
4687 for ( QgsStringMap::iterator it = vendorOptions.begin(); it != vendorOptions.end(); ++it )
4690 if ( it.key() ==
"distance"_L1 )
4692 distanceParser( it.value().split(
',' ) );
4693 distanceFromVendorOption =
true;
4696 else if ( it.key() ==
"graphic-margin"_L1 )
4698 distanceParser( it.value().split(
' ' ) );
4699 distanceFromVendorOption =
true;
4704 if ( !distanceFromVendorOption && !graphicFillElem.elementsByTagName( u
"Size"_s ).isEmpty() )
4706 const QDomElement sizeElement { graphicFillElem.elementsByTagName( u
"Size"_s ).at( 0 ).toElement() };
4708 const double size { sizeElement.text().toDouble( &ok ) };
4711 pointPatternFillSl->setDistanceX( size );
4712 pointPatternFillSl->setDistanceY( size );
4716 return pointPatternFillSl;
4801 attributes.unite(
mMarkerSymbol->usedAttributes( context ) );
4839 auto sl = std::make_unique< QgsCentroidFillSymbolLayer >();
4841 if (
properties.contains( u
"point_on_surface"_s ) )
4842 sl->setPointOnSurface(
properties[u
"point_on_surface"_s].toInt() != 0 );
4843 if (
properties.contains( u
"point_on_all_parts"_s ) )
4844 sl->setPointOnAllParts(
properties[u
"point_on_all_parts"_s].toInt() != 0 );
4845 if (
properties.contains( u
"clip_points"_s ) )
4846 sl->setClipPoints(
properties[u
"clip_points"_s].toInt() != 0 );
4847 if (
properties.contains( u
"clip_on_current_part_only"_s ) )
4848 sl->setClipOnCurrentPartOnly(
properties[u
"clip_on_current_part_only"_s].toInt() != 0 );
4850 sl->restoreOldDataDefinedProperties(
properties );
4857 return u
"CentroidFill"_s;
4885 part.exterior = points;
4887 part.rings = *rings;
4895 mCurrentParts << part;
4900 const double prevOpacity =
mMarker->opacity();
4904 mMarker->setOpacity( prevOpacity );
4913 mCurrentParts.clear();
4920 const double prevOpacity =
mMarker->opacity();
4926 mMarker->setOpacity( prevOpacity );
4931void QgsCentroidFillSymbolLayer::render(
QgsRenderContext &context,
const QVector<QgsCentroidFillSymbolLayer::Part> &parts,
const QgsFeature &feature,
bool selected )
4940 QVector< QgsGeometry > geometryParts;
4941 geometryParts.reserve( parts.size() );
4942 QPainterPath globalPath;
4945 int maxAreaPartIdx = 0;
4947 for (
int i = 0; i < parts.size(); i++ )
4949 const Part part = parts[i];
4952 if ( !geom.
isNull() && !part.rings.empty() )
4958 int area = poly->
area();
4960 if ( area > maxArea )
4970 globalPath.addPolygon( part.exterior );
4971 for (
const QPolygonF &ring : part.rings )
4973 globalPath.addPolygon( ring );
4978 for (
int i = 0; i < parts.size(); i++ )
4983 const Part part = parts[i];
4992 path.addPolygon( part.exterior );
4993 for (
const QPolygonF &ring : part.rings )
4995 path.addPolygon( ring );
5003 painterState.save();
5004 context.
painter()->setClipPath( path );
5011 mMarker->renderPoint( centroid, feature.
isValid() ? &feature :
nullptr, context, -1, selected );
5021 map[u
"clip_points"_s] = QString::number(
mClipPoints );
5028 auto x = std::make_unique< QgsCentroidFillSymbolLayer >();
5031 x->setSubSymbol(
mMarker->clone() );
5044 toSld( doc, element, context );
5052 return mMarker->toSld( doc, element, context );
5062 layers.append( l.release() );
5063 auto marker = std::make_unique<QgsMarkerSymbol>( layers );
5065 auto sl = std::make_unique< QgsCentroidFillSymbolLayer >();
5066 sl->setSubSymbol( marker.release() );
5067 sl->setPointOnAllParts(
false );
5095 attributes.unite(
mMarker->usedAttributes( context ) );
5118 mMarker->setOutputUnit( unit );
5135 return mMarker->usesMapUnits();
5144 mMarker->setMapUnitScale( scale );
5152 return mMarker->mapUnitScale();
5179 imagePath =
properties[u
"imageFile"_s].toString();
5181 if (
properties.contains( u
"coordinate_mode"_s ) )
5201 auto symbolLayer = std::make_unique< QgsRasterFillSymbolLayer >( imagePath );
5202 symbolLayer->setCoordinateMode( mode );
5203 symbolLayer->setOpacity( alpha );
5204 symbolLayer->setOffset(
offset );
5205 symbolLayer->setAngle(
angle );
5206 symbolLayer->setWidth(
width );
5207 if (
properties.contains( u
"offset_unit"_s ) )
5211 if (
properties.contains( u
"offset_map_unit_scale"_s ) )
5215 if (
properties.contains( u
"width_unit"_s ) )
5219 if (
properties.contains( u
"width_map_unit_scale"_s ) )
5226 symbolLayer->setHeight(
properties[u
"height"_s].toDouble() );
5229 symbolLayer->restoreOldDataDefinedProperties(
properties );
5236 QDomElement fillElem = element.firstChildElement( u
"Fill"_s );
5237 if ( fillElem.isNull() )
5240 QDomElement graphicFillElem = fillElem.firstChildElement( u
"GraphicFill"_s );
5241 if ( graphicFillElem.isNull() )
5244 QDomElement graphicElem = graphicFillElem.firstChildElement( u
"Graphic"_s );
5245 if ( graphicElem.isNull() )
5248 QString path, mimeType;
5256 if ( !QFile::exists( path ) )
5261 auto sl = std::make_unique< QgsRasterFillSymbolLayer>( path );
5268 QVariantMap::iterator it =
properties.find( u
"imageFile"_s );
5272 it.value() = pathResolver.
writePath( it.value().toString() );
5274 it.value() = pathResolver.
readPath( it.value().toString() );
5286 return u
"RasterFill"_s;
5302 QPointF
offset = mOffset;
5320 QRectF boundingRect = points.boundingRect();
5321 mBrush.setTransform(
mBrush.transform().translate( boundingRect.left() -
mBrush.transform().dx(), boundingRect.top() -
mBrush.transform().dy() ) );
5333 applyPattern(
mBrush, mImageFilePath, mWidth, mHeight, mOpacity * context.
opacity(), context );
5344 map[u
"imageFile"_s] = mImageFilePath;
5345 map[u
"coordinate_mode"_s] = QString::number(
static_cast< int >( mCoordinateMode ) );
5346 map[u
"alpha"_s] = QString::number( mOpacity );
5350 map[u
"angle"_s] = QString::number(
mAngle );
5352 map[u
"width"_s] = QString::number( mWidth );
5353 map[u
"height"_s] = QString::number( mHeight );
5362 auto sl = std::make_unique< QgsRasterFillSymbolLayer >( mImageFilePath );
5363 sl->setCoordinateMode( mCoordinateMode );
5364 sl->setOpacity( mOpacity );
5365 sl->setOffset( mOffset );
5366 sl->setOffsetUnit( mOffsetUnit );
5367 sl->setOffsetMapUnitScale( mOffsetMapUnitScale );
5369 sl->setWidth( mWidth );
5370 sl->setHeight( mHeight );
5371 sl->setSizeUnit( mSizeUnit );
5372 sl->setSizeMapUnitScale( mSizeMapUnitScale );
5375 return sl.release();
5380 return context.
convertToPainterUnits( std::max( std::fabs( mOffset.x() ), std::fabs( mOffset.y() ) ), mOffsetUnit, mOffsetMapUnitScale );
5402 mImageFilePath = imagePath;
5407 mCoordinateMode = mode;
5426 if ( !hasWidthExpression && !hasHeightExpression && !hasAngleExpression && !hasOpacityExpression && !hasFileExpression )
5432 if ( hasAngleExpression )
5440 if ( !hasWidthExpression && !hasHeightExpression && !hasOpacityExpression && !hasFileExpression )
5445 double width = mWidth;
5446 if ( hasWidthExpression )
5452 if ( hasHeightExpression )
5458 if ( hasOpacityExpression )
5463 QString file = mImageFilePath;
5464 if ( hasFileExpression )
5477void QgsRasterFillSymbolLayer::applyPattern( QBrush &brush,
const QString &imageFilePath,
const double width,
const double height,
const double alpha,
const QgsSymbolRenderContext &context )
5479 double imageWidth = 0;
5480 double imageHeight = 0;
5495 if ( originalSize.isEmpty() )
5498 imageWidth = (
width * originalSize.width() ) / 100.0;
5501 if (
static_cast< int >( imageWidth ) < 1 || 10000.0 < imageWidth )
5514 if ( !originalSize.isValid() )
5517 if ( originalSize.isEmpty() )
5520 imageHeight = (
height * originalSize.height() ) / 100.0;
5523 if (
static_cast< int >( imageHeight ) < 1 || 10000.0 < imageHeight )
5528 if (
width == 0 && imageHeight > 0 )
5530 if ( !originalSize.isValid() )
5533 imageWidth = imageHeight * originalSize.width() / originalSize.height();
5535 else if (
height == 0 && imageWidth > 0 )
5537 if ( !originalSize.isValid() )
5540 imageHeight = imageWidth * originalSize.height() / originalSize.width();
5542 if ( imageWidth == 0 || imageHeight == 0 )
5544 if ( !originalSize.isValid() )
5547 imageWidth = originalSize.width();
5548 imageHeight = originalSize.height();
5558 brush.setTextureImage( img );
5567 : mCountMethod( method )
5583 unsigned long seed = 0;
5590 std::random_device rd;
5591 std::mt19937 mt(
static_cast< int >( rd() ) );
5592 std::uniform_int_distribution<> uniformDist( 1, 999999999 );
5593 seed = uniformDist( mt );
5598 if (
properties.contains( u
"density_area_unit"_s ) )
5600 if (
properties.contains( u
"density_area_unit_scale"_s ) )
5603 if (
properties.contains( u
"clip_points"_s ) )
5605 sl->setClipPoints(
properties[u
"clip_points"_s].toInt() );
5613 return u
"RandomMarkerFill"_s;
5618 mMarker->setColor(
color );
5624 return mMarker ? mMarker->color() :
mColor;
5641 part.exterior = points;
5643 part.rings = *rings;
5645 if ( mRenderingFeature )
5649 mFeatureSymbolOpacity = context.
opacity();
5650 mCurrentParts << part;
5655 const double prevOpacity = mMarker->opacity();
5656 mMarker->setOpacity( mMarker->opacity() * context.
opacity() );
5659 mMarker->setOpacity( prevOpacity );
5663void QgsRandomMarkerFillSymbolLayer::render(
QgsRenderContext &context,
const QVector<QgsRandomMarkerFillSymbolLayer::Part> &parts,
const QgsFeature &feature,
bool selected )
5672 QVector< QgsGeometry > geometryParts;
5673 geometryParts.reserve( parts.size() );
5676 for (
const Part &part : parts )
5679 if ( !geom.
isNull() && !part.rings.empty() )
5682 for (
const QPolygonF &ring : part.rings )
5692 geometryParts << geom;
5696 path.addPolygon( part.exterior );
5697 for (
const QPolygonF &ring : part.rings )
5699 path.addPolygon( ring );
5704 const QgsGeometry geom = geometryParts.count() != 1 ?
QgsGeometry::unaryUnion( geometryParts, QgsGeometryParameters(), context.
feedback() ) : geometryParts.at( 0 );
5709 painterState.save();
5710 context.
painter()->setClipPath( path );
5714 int count = mPointCount;
5721 switch ( mCountMethod )
5733 count = std::max( 0.0, std::ceil( count * ( geom.
area() /
densityArea ) ) );
5740 unsigned long seed = mSeed;
5751 std::sort( randomPoints.begin(), randomPoints.end(), [](
const QgsPointXY & a,
const QgsPointXY & b )->bool
5753 return a.y() < b.y();
5756 QgsExpressionContextScope *scope =
new QgsExpressionContextScope();
5757 QgsExpressionContextScopePopper scopePopper( context.
expressionContext(), scope );
5759 const bool needsExpressionContext = mMarker->hasDataDefinedProperties();
5764 for (
const QgsPointXY &p : std::as_const( randomPoints ) )
5766 if ( needsExpressionContext )
5768 mMarker->renderPoint( QPointF( p.x(), p.y() ), feature.
isValid() ? &feature :
nullptr, context, -1, selected );
5777 map.insert( u
"count_method"_s, QString::number(
static_cast< int >( mCountMethod ) ) );
5778 map.insert( u
"point_count"_s, QString::number( mPointCount ) );
5779 map.insert( u
"density_area"_s, QString::number( mDensityArea ) );
5782 map.insert( u
"seed"_s, QString::number( mSeed ) );
5783 map.insert( u
"clip_points"_s, QString::number( mClipPoints ) );
5789 auto res = std::make_unique< QgsRandomMarkerFillSymbolLayer >( mPointCount, mCountMethod, mDensityArea, mSeed );
5792 res->setDensityAreaUnit( mDensityAreaUnit );
5793 res->setDensityAreaUnitScale( mDensityAreaUnitScale );
5794 res->mClipPoints = mClipPoints;
5795 res->setSubSymbol( mMarker->clone() );
5797 return res.release();
5820 return mMarker.get();
5832 mColor = mMarker->color();
5841 attributes.unite( mMarker->usedAttributes( context ) );
5850 if ( mMarker && mMarker->hasDataDefinedProperties() )
5887 return mCountMethod;
5892 mCountMethod = method;
5897 return mDensityArea;
5902 mDensityArea = area;
5909 mRenderingFeature =
true;
5910 mCurrentParts.clear();
5915 mRenderingFeature =
false;
5917 const double prevOpacity = mMarker->opacity();
5918 mMarker->setOpacity( mMarker->opacity() * mFeatureSymbolOpacity );
5920 render( context, mCurrentParts, feature,
false );
5922 mFeatureSymbolOpacity = 1;
5923 mMarker->setOpacity( prevOpacity );
5931 mDensityAreaUnit = unit;
5934 mMarker->setOutputUnit( unit );
5942 return mMarker->outputUnit();
5951 return mMarker->usesMapUnits();
5960 mMarker->setMapUnitScale( scale );
5968 return mMarker->mapUnitScale();
@ PreferVector
Prefer vector-based rendering, when the result will still be visually near-identical to a raster-base...
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.
@ IsSymbolLayerSubSymbol
Symbol is being rendered as a sub-symbol of a QgsSymbolLayer.
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.
@ CanCalculateMaskGeometryPerFeature
If present, indicates that mask geometry can safely be calculated per feature for the symbol layer....
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.
QFlags< SymbolLayerFlag > SymbolLayerFlags
Symbol layer flags.
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.
@ RenderLayerTree
The render is for a layer tree display where map based properties are not available and where avoidan...
@ 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.
QFlags< SymbolRenderHint > SymbolRenderHints
Symbol render hints.
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.
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.
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...
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.
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 setSubSymbol(QgsSymbol *symbol) final
Sets layer's subsymbol. takes ownership of the passed symbol.
bool pointOnSurface() const
QgsMapUnitScale mapUnitScale() const override
static std::unique_ptr< QgsSymbolLayer > create(const QVariantMap &properties=QVariantMap())
Creates a new QgsCentroidFillSymbolLayer using the specified properties map containing symbol propert...
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.
Q_DECL_DEPRECATED void toSld(QDomDocument &doc, QDomElement &element, const QVariantMap &props) const override
Saves the symbol layer as SLD.
static std::unique_ptr< QgsSymbolLayer > createFromSld(QDomElement &element)
~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 QString type() const =0
Returns a string representing the color ramp type.
static QColor colorFromString(const QString &string)
Decodes a string into a color value.
static QString colorToString(const QColor &color)
Encodes a color into a string value.
static QString typeString()
Returns the string identifier for QgsCptCityColorRamp.
static std::unique_ptr< QgsColorRamp > create(const QVariantMap &properties=QVariantMap())
Creates the symbol layer.
double area() const override
Returns the planar, 2-dimensional area of the geometry.
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.
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.
Encapsulates parameters under which a geometry operation is performed.
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 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 QgsGeometry unaryUnion(const QVector< QgsGeometry > &geometries, const QgsGeometryParameters ¶meters=QgsGeometryParameters(), QgsFeedback *feedback=nullptr)
Compute the unary union on a list of geometries.
QgsGeometry buffer(double distance, int segments, QgsFeedback *feedback=nullptr) const
Returns a buffer region around this geometry having the given width and with a specified number of se...
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometry *geometry, double precision=0.0, Qgis::GeosCreationFlags flags=Qgis::GeosCreationFlag::SkipEmptyInteriorRings)
Creates and returns a new geometry engine representing the specified geometry using precision on a gr...
static std::unique_ptr< 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.
static std::unique_ptr< QgsSymbolLayer > create(const QVariantMap &properties=QVariantMap())
Creates a new QgsGradientFillSymbolLayer using the specified properties map containing symbol propert...
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.
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
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.
Qgis::SymbolLayerFlags flags() const override
Returns flags which control the symbol layer's behavior.
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].
std::unique_ptr< QgsColorRamp > mGradientRamp
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.
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
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.
double dxfWidth(QgsSymbolRenderContext &context) const override
Gets line width.
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.
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.
Q_DECL_DEPRECATED 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.
static std::unique_ptr< QgsSymbolLayer > createFromSld(QDomElement &element)
Creates a new QgsLinePatternFillSymbolLayer from a SLD element.
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
static std::unique_ptr< QgsSymbolLayer > create(const QVariantMap &properties=QVariantMap())
Creates a new QgsLinePatternFillSymbolLayer from a properties map.
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
Line string geometry type, with support for z-dimension and m-values.
static std::unique_ptr< QgsLineString > fromQPolygonF(const QPolygonF &polygon)
Returns a new linestring from a QPolygonF polygon input.
QPolygonF asQPolygonF() const override
Returns a QPolygonF representing the points.
A line symbol type, for rendering LineString and MultiLineString geometries.
double mapUnitsPerPixel() const
Returns the current map units per pixel.
Struct for storing maximum and minimum scales for measurements in map units.
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, const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE(), Qgis::StringFormat format=Qgis::StringFormat::PlainText)
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.
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.
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.
static std::unique_ptr< QgsSymbolLayer > create(const QVariantMap &properties=QVariantMap())
Creates a new QgsPointPatternFillSymbolLayer using the specified properties map containing symbol pro...
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()
static std::unique_ptr< QgsSymbolLayer > createFromSld(QDomElement &element)
QgsMapUnitScale mRandomDeviationXMapUnitScale
Q_DECL_DEPRECATED 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.
bool mMarkerSymbolRenderStarted
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...
bool isActive(int key) const final
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.
~QgsRandomMarkerFillSymbolLayer() override
bool setSubSymbol(QgsSymbol *symbol) final
Sets layer's subsymbol. takes ownership of the passed symbol.
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...
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 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.
static std::unique_ptr< QgsSymbolLayer > create(const QVariantMap &properties=QVariantMap())
Creates a new QgsRandomMarkerFillSymbolLayer using the specified properties map containing symbol pro...
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.
bool rendersIdenticallyTo(const QgsSymbolLayer *other) const override
Returns true if this symbol layer will always render identically to an other symbol layer.
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
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 ...
Qgis::SymbolLayerFlags flags() const override
Returns flags which control the symbol layer's behavior.
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.
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.
double height() const
Returns the height used for scaling the image used in the fill.
static std::unique_ptr< QgsSymbolLayer > create(const QVariantMap &properties=QVariantMap())
Creates a new QgsRasterFillSymbolLayer from a properties map.
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.
static std::unique_ptr< QgsSymbolLayer > createFromSld(QDomElement &element)
Creates a new QgsRasterFillSymbolLayer from a SLD element.
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.
Contains information about the context of a rendering operation.
double scaleFactor() const
Returns the scaling factor for the render to convert painter units to physical sizes.
double convertToMapUnits(double size, Qgis::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale()) const
Converts a size from the specified units to map units.
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.
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 setRasterizedRenderingPolicy(Qgis::RasterizedRenderingPolicy policy)
Sets the policy controlling when rasterisation of content during renders is permitted.
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...
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.
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.
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.
static std::unique_ptr< QgsSymbolLayer > createFromSld(QDomElement &element)
Creates a new QgsSVGFillSymbolLayer from a SLD element.
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
Q_DECL_DEPRECATED void toSld(QDomDocument &doc, QDomElement &element, const QVariantMap &props) const override
Saves the symbol layer as SLD.
static std::unique_ptr< QgsSymbolLayer > create(const QVariantMap &properties=QVariantMap())
Creates a new QgsSVGFillSymbolLayer from a properties map.
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.
@ NoSave
Do not save the current painter 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 std::unique_ptr< 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.
Qgis::SymbolLayerFlags flags() const override
Returns flags which control the symbol layer's behavior.
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)
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::SymbolLayerFlags flags() const override
Returns flags which control the symbol layer's behavior.
Qgis::RenderUnit mOffsetUnit
~QgsSimpleFillSymbolLayer() override
Q_DECL_DEPRECATED 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
static std::unique_ptr< QgsSymbolLayer > create(const QVariantMap &properties=QVariantMap())
Creates a new QgsSimpleFillSymbolLayer using the specified properties map containing symbol propertie...
QImage toTiledPatternImage() const override
Renders the symbol layer as an image that can be used as a seamless pattern fill for polygons,...
static std::unique_ptr< QgsSymbolLayer > createFromSld(QDomElement &element)
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.
double dxfWidth(QgsSymbolRenderContext &context) const override
Gets line width.
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...
Holds SLD export options and other information related to SLD export of a QGIS layer style.
QString exportFilePath() const
Returns the export file path for the SLD.
void setExtraProperties(const QVariantMap &properties)
Sets the open ended set of properties that can drive/inform the SLD encoding.
void pushWarning(const QString &warning)
Pushes a warning message generated during the conversion.
Qgis::SldExportOptions exportOptions() const
Returns the export options.
QVariantMap extraProperties() const
Returns the open ended set of properties that can drive/inform the SLD encoding.
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 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 std::unique_ptr< QgsSymbolLayer > createMarkerLayerFromSld(QDomElement &element)
Creates a new marker layer from a SLD DOM element.
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 Q_DECL_DEPRECATED 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 std::unique_ptr< QgsSymbolLayer > createLineLayerFromSld(QDomElement &element)
Creates a new line layer from a SLD DOM element.
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 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)
Extracts properties from an SLD marker definition.
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)
Lossy-encodes a color to a string.
static bool fillFromSld(QDomElement &element, Qt::BrushStyle &brushStyle, QColor &color)
static Q_DECL_DEPRECATED void fillToSld(QDomDocument &doc, QDomElement &element, Qt::BrushStyle brushStyle, const QColor &color=QColor())
Exports fill details to an SLD element.
static Qgis::RenderUnit decodeSldUom(const QString &str, double *scaleFactor=nullptr)
Decodes a SLD unit of measure string to a render unit.
static Q_DECL_DEPRECATED void createGeometryElement(QDomDocument &doc, QDomElement &element, const QString &geomFunc)
Creates an SLD geometry element.
static double estimateMaxSymbolBleed(QgsSymbol *symbol, const QgsRenderContext &context)
Returns the maximum estimated bleed for the symbol.
static Q_DECL_DEPRECATED void wellKnownMarkerToSld(QDomDocument &doc, QDomElement &element, const QString &name, const QColor &color, const QColor &strokeColor, Qt::PenStyle strokeStyle, double strokeWidth=-1, double size=-1)
Exports a marker to SLD.
static Qt::PenStyle decodePenStyle(const QString &str)
static Q_DECL_DEPRECATED void createRotationElement(QDomDocument &doc, QDomElement &element, const QString &rotationFunc)
Creates SLD rotation element.
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 QString encodePenJoinStyle(Qt::PenJoinStyle style)
static QgsStringMap getVendorOptionList(QDomElement &element)
static QPointF decodePoint(const QString &string)
Decodes a QSizeF from a string.
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.
static void lineToSld(QDomDocument &doc, QDomElement &element, Qt::PenStyle penStyle, const QColor &color, QgsSldExportContext &context, double width=-1, const Qt::PenJoinStyle *penJoinStyle=nullptr, const Qt::PenCapStyle *penCapStyle=nullptr, const QVector< qreal > *customDashPattern=nullptr, double dashOffset=0.0)
void copyCommonProperties(QgsSymbolLayer *destLayer) const
Copies all common base class properties from this layer to another symbol layer.
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.
bool installMasks(QgsRenderContext &context, bool recursive, const QRectF &rect=QRectF())
When rendering, install masks on context painter.
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.
@ GradientType
Gradient fill type.
@ SecondaryColor
Secondary color (eg for gradient fills).
@ File
Filename, eg for svg files.
@ GradientReference2Y
Gradient reference point 2 y.
@ GradientReference1X
Gradient reference point 1 x.
@ OffsetY
Vertical offset.
@ OffsetX
Horizontal offset.
@ GradientReference1Y
Gradient reference point 1 y.
@ GradientSpread
Gradient spread mode.
@ ShapeburstMaxDistance
Shapeburst fill from edge distance.
@ StrokeStyle
Stroke style (eg solid, dashed).
@ DistanceY
Vertical distance between points.
@ DensityArea
Density area.
@ ClipPoints
Whether markers should be clipped to polygon boundaries.
@ LineClipping
Line clipping mode.
@ ShapeburstIgnoreRings
Shapeburst ignore rings.
@ ShapeburstUseWholeShape
Shapeburst use whole shape.
@ DisplacementX
Horizontal displacement.
@ CoordinateMode
Gradient coordinate mode.
@ FillStyle
Fill style (eg solid, dots).
@ GradientReference2X
Gradient reference point 2 x.
@ StrokeColor
Stroke color.
@ BlurRadius
Shapeburst blur radius.
@ MarkerClipping
Marker clipping mode.
@ RandomSeed
Random number seed.
@ LineAngle
Line angle, or angle of hash lines for hash line symbols.
@ JoinStyle
Line join style.
@ RandomOffsetY
Random offset Y.
@ DisplacementY
Vertical displacement.
@ DistanceX
Horizontal distance between points.
@ GradientReference1IsCentroid
Gradient reference point 1 is centroid.
@ StrokeWidth
Stroke width.
@ GradientReference2IsCentroid
Gradient reference point 2 is centroid.
@ LineDistance
Distance between lines, or length of lines for hash line symbols.
@ RandomOffsetX
Random offset X.
void restoreOldDataDefinedProperties(const QVariantMap &stringMap)
Restores older data defined properties from string map.
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 bool rendersIdenticallyTo(const QgsSymbolLayer *other) const
Returns true if this symbol layer will always render identically to an other symbol layer.
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.
virtual Qgis::SymbolLayerFlags flags() const
Returns flags which control the symbol layer's behavior.
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.
QgsSymbolLayer(const QgsSymbolLayer &other)
Encapsulates the context in which a symbol is being rendered.
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.
bool forceVectorRendering() const
Returns true if symbol must be rendered using vector methods, and optimisations like pre-rendered ima...
qreal opacity() const
Returns the opacity for the symbol.
QgsRenderContext & renderContext()
Returns a reference to the context's render context.
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, bool silenceNullWarnings=false)
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
T qgsgeometry_cast(QgsAbstractGeometry *geom)
#define DEFAULT_SIMPLEFILL_JOINSTYLE
#define DEFAULT_SIMPLEFILL_COLOR
#define DEFAULT_SIMPLEFILL_STYLE
#define DEFAULT_SIMPLEFILL_BORDERSTYLE
#define DEFAULT_SIMPLEFILL_BORDERCOLOR
#define DEFAULT_SIMPLEFILL_BORDERWIDTH
#define QgsDebugError(str)
QList< QgsSymbolLayer * > QgsSymbolLayerList
Single variable definition for use within a QgsExpressionContextScope.