46#include <QDomDocument>
49#include <QPagedPaintDevice>
52#include <QSvgRenderer>
55using namespace Qt::StringLiterals;
107void QgsSimpleFillSymbolLayer::applyDataDefinedSymbology(
QgsSymbolRenderContext &context, QBrush &brush, QPen &pen, QPen &selPen )
132 penColor.setAlphaF( context.
opacity() * penColor.alphaF() );
133 pen.setColor( penColor );
141 double width = exprVal.toDouble( &ok );
145 pen.setWidthF( width );
146 selPen.setWidthF( width );
183 if ( props.contains( u
"color"_s ) )
185 if ( props.contains( u
"style"_s ) )
187 if ( props.contains( u
"color_border"_s ) )
192 else if ( props.contains( u
"outline_color"_s ) )
196 else if ( props.contains( u
"line_color"_s ) )
201 if ( props.contains( u
"style_border"_s ) )
206 else if ( props.contains( u
"outline_style"_s ) )
210 else if ( props.contains( u
"line_style"_s ) )
214 if ( props.contains( u
"width_border"_s ) )
219 else if ( props.contains( u
"outline_width"_s ) )
221 strokeWidth = props[u
"outline_width"_s].toDouble();
223 else if ( props.contains( u
"line_width"_s ) )
227 if ( props.contains( u
"offset"_s ) )
229 if ( props.contains( u
"joinstyle"_s ) )
234 if ( props.contains( u
"border_width_unit"_s ) )
238 else if ( props.contains( u
"outline_width_unit"_s ) )
242 else if ( props.contains( u
"line_width_unit"_s ) )
246 if ( props.contains( u
"offset_unit"_s ) )
249 if ( props.contains( u
"border_width_map_unit_scale"_s ) )
251 if ( props.contains( u
"offset_map_unit_scale"_s ) )
254 sl->restoreOldDataDefinedProperties( props );
262 return u
"SimpleFill"_s;
279 selColor.setAlphaF( context.
opacity() );
338 if (
mBrush.style() == Qt::SolidPattern ||
mBrush.style() == Qt::NoBrush || !
dynamic_cast<QPagedPaintDevice *
>( p->device() ) )
350 p->setPen( Qt::NoPen );
354 p->setBrush( Qt::NoBrush );
371 map[u
"outline_width"_s] = QString::number(
mStrokeWidth );
398 toSld( doc, element, context );
407 QDomElement symbolizerElem = doc.createElement( u
"se:PolygonSymbolizer"_s );
408 if ( !props.value( u
"uom"_s, QString() ).toString().isEmpty() )
409 symbolizerElem.setAttribute( u
"uom"_s, props.value( u
"uom"_s, QString() ).toString() );
410 element.appendChild( symbolizerElem );
416 bool exportOk {
false };
420 if ( ! image.isNull() )
423 QDomElement fillElem = doc.createElement( u
"se:Fill"_s );
424 symbolizerElem.appendChild( fillElem );
425 QDomElement graphicFillElem = doc.createElement( u
"se:GraphicFill"_s );
426 fillElem.appendChild( graphicFillElem );
427 QDomElement graphicElem = doc.createElement( u
"se:Graphic"_s );
428 graphicFillElem.appendChild( graphicElem );
431 QString pngPath { info.completeSuffix().isEmpty() ? context.
exportFilePath() : context.
exportFilePath().chopped( info.completeSuffix().length() ).append( u
"png"_s ) };
432 pngPath = QgsFileUtils::uniquePath( pngPath );
433 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();
635 bool refPoint1IsCentroid =
false;
637 bool refPoint2IsCentroid =
false;
642 if ( props.contains( u
"type"_s ) )
644 if ( props.contains( u
"coordinate_mode"_s ) )
646 if ( props.contains( u
"spread"_s ) )
648 if ( props.contains( u
"color_type"_s ) )
650 if ( props.contains( u
"gradient_color"_s ) )
655 else if ( props.contains( u
"color"_s ) )
659 if ( props.contains( u
"gradient_color2"_s ) )
664 if ( props.contains( u
"reference_point1"_s ) )
666 if ( props.contains( u
"reference_point1_iscentroid"_s ) )
667 refPoint1IsCentroid = props[u
"reference_point1_iscentroid"_s].toInt();
668 if ( props.contains( u
"reference_point2"_s ) )
670 if ( props.contains( u
"reference_point2_iscentroid"_s ) )
671 refPoint2IsCentroid = props[u
"reference_point2_iscentroid"_s].toInt();
672 if ( props.contains( u
"angle"_s ) )
673 angle = props[u
"angle"_s].toDouble();
675 if ( props.contains( u
"offset"_s ) )
692 if ( props.contains( u
"offset_unit"_s ) )
694 if ( props.contains( u
"offset_map_unit_scale"_s ) )
697 sl->setReferencePoint1IsCentroid( refPoint1IsCentroid );
699 sl->setReferencePoint2IsCentroid( refPoint2IsCentroid );
700 sl->setAngle(
angle );
702 sl->setColorRamp( gradientRamp );
704 sl->restoreOldDataDefinedProperties( props );
721 return u
"GradientFill"_s;
724void QgsGradientFillSymbolLayer::applyDataDefinedSymbology(
QgsSymbolRenderContext &context,
const QPolygonF &points )
769 if ( currentType == QObject::tr(
"linear" ) )
773 else if ( currentType == QObject::tr(
"radial" ) )
777 else if ( currentType == QObject::tr(
"conical" ) )
791 if ( currentCoordMode == QObject::tr(
"feature" ) )
795 else if ( currentCoordMode == QObject::tr(
"viewport" ) )
809 if ( currentSpread == QObject::tr(
"pad" ) )
813 else if ( currentSpread == QObject::tr(
"repeat" ) )
817 else if ( currentSpread == QObject::tr(
"reflect" ) )
864 if ( refPoint1IsCentroid || refPoint2IsCentroid )
869 QRectF bbox = points.boundingRect();
870 double centroidX = ( centroid.x() - bbox.left() ) / bbox.width();
871 double centroidY = ( centroid.y() - bbox.top() ) / bbox.height();
873 if ( refPoint1IsCentroid )
875 refPoint1X = centroidX;
876 refPoint1Y = centroidY;
878 if ( refPoint2IsCentroid )
880 refPoint2X = centroidX;
881 refPoint2Y = centroidY;
887 spread, QPointF( refPoint1X, refPoint1Y ), QPointF( refPoint2X, refPoint2Y ),
angle );
890QPointF QgsGradientFillSymbolLayer::rotateReferencePoint( QPointF refPoint,
double angle )
895 QLineF refLine = QLineF( QPointF( 0.5, 0.5 ), refPoint );
897 refLine.setAngle( refLine.angle() +
angle );
899 QPointF rotatedReferencePoint = refLine.p2();
901 if ( rotatedReferencePoint.x() > 1 )
902 rotatedReferencePoint.setX( 1 );
903 if ( rotatedReferencePoint.x() < 0 )
904 rotatedReferencePoint.setX( 0 );
905 if ( rotatedReferencePoint.y() > 1 )
906 rotatedReferencePoint.setY( 1 );
907 if ( rotatedReferencePoint.y() < 0 )
908 rotatedReferencePoint.setY( 0 );
910 return rotatedReferencePoint;
917 QPointF referencePoint1, QPointF referencePoint2,
const double angle )
922 QColor fillColor2 =
color2;
923 fillColor2.setAlphaF( context.
opacity() * fillColor2.alphaF() );
934 gradient = QLinearGradient( rotatedReferencePoint1, rotatedReferencePoint2 );
937 gradient = QRadialGradient( rotatedReferencePoint1, QLineF( rotatedReferencePoint1, rotatedReferencePoint2 ).length() );
940 gradient = QConicalGradient( rotatedReferencePoint1, QLineF( rotatedReferencePoint1, rotatedReferencePoint2 ).
angle() );
946 gradient.setCoordinateMode( QGradient::ObjectBoundingMode );
949 gradient.setCoordinateMode( QGradient::StretchToDeviceMode );
955 gradient.setSpread( QGradient::PadSpread );
958 gradient.setSpread( QGradient::ReflectSpread );
961 gradient.setSpread( QGradient::RepeatSpread );
970 QgsGradientColorRamp *gradRamp =
static_cast<QgsGradientColorRamp *
>( gradientRamp );
977 gradient.setColorAt( 1.0, fillColor2 );
981 brush = QBrush( gradient );
988 selColor.setAlphaF( context.
opacity() );
1005 applyDataDefinedSymbology( context, points );
1009 p->setPen( Qt::NoPen );
1043 map[u
"type"_s] = QString::number(
static_cast<int>(
mGradientType ) );
1044 map[u
"coordinate_mode"_s] = QString::number(
static_cast< int >(
mCoordinateMode ) );
1045 map[u
"spread"_s] = QString::number(
static_cast< int >(
mGradientSpread ) );
1050 map[u
"angle"_s] = QString::number(
mAngle );
1076 return sl.release();
1141 if ( props.contains( u
"color_type"_s ) )
1145 if ( props.contains( u
"shapeburst_color"_s ) )
1150 else if ( props.contains( u
"color"_s ) )
1155 if ( props.contains( u
"shapeburst_color2"_s ) )
1160 else if ( props.contains( u
"gradient_color2"_s ) )
1164 if ( props.contains( u
"blur_radius"_s ) )
1166 blurRadius = props[u
"blur_radius"_s].toInt();
1168 if ( props.contains( u
"use_whole_shape"_s ) )
1172 if ( props.contains( u
"max_distance"_s ) )
1174 maxDistance = props[u
"max_distance"_s].toDouble();
1176 if ( props.contains( u
"offset"_s ) )
1195 if ( props.contains( u
"offset_unit"_s ) )
1199 if ( props.contains( u
"distance_unit"_s ) )
1203 if ( props.contains( u
"offset_map_unit_scale"_s ) )
1207 if ( props.contains( u
"distance_map_unit_scale"_s ) )
1211 if ( props.contains( u
"ignore_rings"_s ) )
1213 sl->setIgnoreRings( props[u
"ignore_rings"_s].toInt() );
1217 sl->setColorRamp( gradientRamp );
1220 sl->restoreOldDataDefinedProperties( props );
1222 return sl.release();
1227 return u
"ShapeburstFill"_s;
1237 if ( mGradientRamp.get() == ramp )
1240 mGradientRamp.reset( ramp );
1243void QgsShapeburstFillSymbolLayer::applyDataDefinedSymbology(
QgsSymbolRenderContext &context, QColor &color, QColor &color2,
int &blurRadius,
bool &useWholeShape,
1244 double &maxDistance,
bool &ignoreRings )
1301 selColor.setAlphaF( context.
opacity() );
1302 mSelBrush = QBrush( selColor );
1319 if ( useSelectedColor )
1322 p->setBrush( mSelBrush );
1323 QPointF
offset = mOffset;
1358 int outputPixelMaxDist = 0;
1366 std::unique_ptr< QgsGradientColorRamp > twoColorGradientRamp;
1369 twoColorGradientRamp = std::make_unique< QgsGradientColorRamp >( color1,
color2 );
1373 p->setPen( QPen( Qt::NoPen ) );
1378 int pointsWidth =
static_cast< int >( std::round( points.boundingRect().width() ) );
1379 int pointsHeight =
static_cast< int >( std::round( points.boundingRect().height() ) );
1380 int imWidth = pointsWidth + ( sideBuffer * 2 );
1381 int imHeight = pointsHeight + ( sideBuffer * 2 );
1387 auto fillImage = std::make_unique< QImage >( imWidth,
1388 imHeight, QImage::Format_ARGB32_Premultiplied );
1389 if ( fillImage->isNull() )
1399 auto alphaImage = std::make_unique< QImage >( fillImage->width(), fillImage->height(), QImage::Format_ARGB32_Premultiplied );
1400 if ( alphaImage->isNull() )
1412 fillImage->fill( Qt::black );
1418 alphaImage->fill( Qt::transparent );
1424 QPainter imgPainter;
1425 imgPainter.begin( alphaImage.get() );
1426 imgPainter.setRenderHint( QPainter::Antialiasing,
true );
1427 imgPainter.setBrush( QBrush( Qt::white ) );
1428 imgPainter.setPen( QPen( Qt::black ) );
1429 imgPainter.translate( -points.boundingRect().left() + sideBuffer, - points.boundingRect().top() + sideBuffer );
1438 imgPainter.begin( fillImage.get() );
1441 imgPainter.drawImage( 0, 0, *alphaImage );
1448 imgPainter.setBrush( QBrush( Qt::white ) );
1449 imgPainter.setPen( QPen( Qt::black ) );
1450 imgPainter.translate( -points.boundingRect().left() + sideBuffer, - points.boundingRect().top() + sideBuffer );
1459 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 )
1623 dtArray[ idx ] =
INF;
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 );
1736 return sl.release();
1741 double offsetBleed = context.
convertToPainterUnits( std::max( std::fabs( mOffset.x() ), std::fabs( mOffset.y() ) ), mOffsetUnit, mOffsetMapUnitScale );
1752 mDistanceUnit = unit;
1758 if ( mDistanceUnit == mOffsetUnit )
1760 return mDistanceUnit;
1773 mDistanceMapUnitScale = scale;
1774 mOffsetMapUnitScale = scale;
1779 if ( mDistanceMapUnitScale == mOffsetMapUnitScale )
1781 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;
1972 mPatternWidthMapUnitScale == mSvgStrokeWidthMapUnitScale &&
1975 return mPatternWidthMapUnitScale;
1985 mSvgFilePath = svgPath;
1986 setDefaultSvgParams();
2009 std::unique_ptr< QgsSVGFillSymbolLayer > symbolLayer;
2012 symbolLayer = std::make_unique< QgsSVGFillSymbolLayer >(
svgFilePath, width,
angle );
2018 data = QByteArray::fromHex(
properties[u
"data"_s].toString().toLocal8Bit() );
2020 symbolLayer = std::make_unique< QgsSVGFillSymbolLayer >( data, width,
angle );
2024 if (
properties.contains( u
"svgFillColor"_s ) )
2029 else if (
properties.contains( u
"color"_s ) )
2033 if (
properties.contains( u
"svgOutlineColor"_s ) )
2038 else if (
properties.contains( u
"outline_color"_s ) )
2042 else if (
properties.contains( u
"line_color"_s ) )
2046 if (
properties.contains( u
"svgOutlineWidth"_s ) )
2049 symbolLayer->setSvgStrokeWidth(
properties[u
"svgOutlineWidth"_s].toDouble() );
2051 else if (
properties.contains( u
"outline_width"_s ) )
2053 symbolLayer->setSvgStrokeWidth(
properties[u
"outline_width"_s].toDouble() );
2055 else if (
properties.contains( u
"line_width"_s ) )
2057 symbolLayer->setSvgStrokeWidth(
properties[u
"line_width"_s].toDouble() );
2061 if (
properties.contains( u
"pattern_width_unit"_s ) )
2065 if (
properties.contains( u
"pattern_width_map_unit_scale"_s ) )
2069 if (
properties.contains( u
"svg_outline_width_unit"_s ) )
2073 if (
properties.contains( u
"svg_outline_width_map_unit_scale"_s ) )
2077 if (
properties.contains( u
"outline_width_unit"_s ) )
2081 if (
properties.contains( u
"outline_width_map_unit_scale"_s ) )
2086 if (
properties.contains( u
"parameters"_s ) )
2092 symbolLayer->restoreOldDataDefinedProperties(
properties );
2094 return symbolLayer.release();
2099 QVariantMap::iterator it =
properties.find( u
"svgFile"_s );
2111 return u
"SVGFill"_s;
2114void QgsSVGFillSymbolLayer::applyPattern( QBrush &brush,
const QString &svgFilePath,
double patternWidth,
Qgis::RenderUnit patternWidthUnit,
2115 const QColor &svgFillColor,
const QColor &svgStrokeColor,
double svgStrokeWidth,
2119 if ( mSvgViewBox.isNull() )
2126 if (
static_cast< int >( size ) < 1.0 || 10000.0 < size )
2128 brush.setTextureImage( QImage() );
2132 bool fitsInCache =
true;
2140 double hwRatio = 1.0;
2141 if ( patternPict.width() > 0 )
2143 hwRatio =
static_cast< double >( patternPict.height() ) /
static_cast< double >( patternPict.width() );
2145 patternImage = QImage(
static_cast< int >( size ),
static_cast< int >( size * hwRatio ), QImage::Format_ARGB32_Premultiplied );
2146 patternImage.fill( 0 );
2148 QPainter p( &patternImage );
2149 p.drawPicture( QPointF( size / 2, size * hwRatio / 2 ), patternPict );
2152 QTransform brushTransform;
2155 QImage transparentImage = patternImage.copy();
2157 brush.setTextureImage( transparentImage );
2161 brush.setTextureImage( patternImage );
2163 brush.setTransform( brushTransform );
2171 applyPattern(
mBrush, mSvgFilePath, mPatternWidth, mPatternWidthUnit,
mColor, mSvgStrokeColor, mSvgStrokeWidth, mSvgStrokeWidthUnit, context, mPatternWidthMapUnitScale, mSvgStrokeWidthMapUnitScale, evaluatedParameters );
2195 mStroke->renderPolyline( points, context.
feature(), context.
renderContext(), -1, useSelectedColor );
2198 for (
auto ringIt = rings->constBegin(); ringIt != rings->constEnd(); ++ringIt )
2200 mStroke->renderPolyline( *ringIt, context.
feature(), context.
renderContext(), -1, useSelectedColor );
2209 if ( !mSvgFilePath.isEmpty() )
2211 map.insert( u
"svgFile"_s, mSvgFilePath );
2215 map.insert( u
"data"_s, QString( mSvgData.toHex() ) );
2218 map.insert( u
"width"_s, QString::number( mPatternWidth ) );
2219 map.insert( u
"angle"_s, QString::number(
mAngle ) );
2224 map.insert( u
"outline_width"_s, QString::number( mSvgStrokeWidth ) );
2241 std::unique_ptr< QgsSVGFillSymbolLayer > clonedLayer;
2242 if ( !mSvgFilePath.isEmpty() )
2244 clonedLayer = std::make_unique< QgsSVGFillSymbolLayer >( mSvgFilePath, mPatternWidth,
mAngle );
2245 clonedLayer->setSvgFillColor(
mColor );
2246 clonedLayer->setSvgStrokeColor( mSvgStrokeColor );
2247 clonedLayer->setSvgStrokeWidth( mSvgStrokeWidth );
2251 clonedLayer = std::make_unique< QgsSVGFillSymbolLayer >( mSvgData, mPatternWidth,
mAngle );
2254 clonedLayer->setPatternWidthUnit( mPatternWidthUnit );
2255 clonedLayer->setPatternWidthMapUnitScale( mPatternWidthMapUnitScale );
2256 clonedLayer->setSvgStrokeWidthUnit( mSvgStrokeWidthUnit );
2257 clonedLayer->setSvgStrokeWidthMapUnitScale( mSvgStrokeWidthMapUnitScale );
2261 clonedLayer->setParameters( mParameters );
2265 clonedLayer->setSubSymbol( mStroke->clone() );
2269 return clonedLayer.release();
2276 toSld( doc, element, context );
2282 QDomElement symbolizerElem = doc.createElement( u
"se:PolygonSymbolizer"_s );
2283 if ( !props.value( u
"uom"_s, QString() ).toString().isEmpty() )
2284 symbolizerElem.setAttribute( u
"uom"_s, props.value( u
"uom"_s, QString() ).toString() );
2285 element.appendChild( symbolizerElem );
2289 QDomElement fillElem = doc.createElement( u
"se:Fill"_s );
2290 symbolizerElem.appendChild( fillElem );
2292 QDomElement graphicFillElem = doc.createElement( u
"se:GraphicFill"_s );
2293 fillElem.appendChild( graphicFillElem );
2295 QDomElement graphicElem = doc.createElement( u
"se:Graphic"_s );
2296 graphicFillElem.appendChild( graphicElem );
2298 if ( !mSvgFilePath.isEmpty() )
2310 context.
pushWarning( QObject::tr(
"Exporting embedded SVG content to SLD is not supported" ) );
2316 double angle = props.value( u
"angle"_s, u
"0"_s ).toDouble( &ok );
2319 angleFunc = u
"%1 + %2"_s.arg( props.value( u
"angle"_s, u
"0"_s ).toString() ).arg(
mAngle );
2332 mStroke->toSld( doc, element, context );
2345 return mStroke.get();
2352 mStroke.reset(
nullptr );
2365 mStroke.reset( lineSymbol );
2375 if ( mStroke && mStroke->symbolLayer( 0 ) )
2377 double subLayerBleed = mStroke->symbolLayer( 0 )->estimateMaxBleed( context );
2378 return subLayerBleed;
2388 return QColor( Qt::black );
2390 return mStroke->
color();
2397 attr.unite( mStroke->usedAttributes( context ) );
2405 if ( mStroke && mStroke->hasDataDefinedProperties() )
2412 QString path, mimeType;
2414 Qt::PenStyle penStyle;
2415 double size, strokeWidth;
2417 QDomElement fillElem = element.firstChildElement( u
"Fill"_s );
2418 if ( fillElem.isNull() )
2421 QDomElement graphicFillElem = fillElem.firstChildElement( u
"GraphicFill"_s );
2422 if ( graphicFillElem.isNull() )
2425 QDomElement graphicElem = graphicFillElem.firstChildElement( u
"Graphic"_s );
2426 if ( graphicElem.isNull() )
2432 if ( mimeType !=
"image/svg+xml"_L1 )
2437 double scaleFactor = 1.0;
2438 const QString uom = element.attribute( u
"uom"_s );
2440 size = size * scaleFactor;
2441 strokeWidth = strokeWidth * scaleFactor;
2448 double d = angleFunc.toDouble( &ok );
2453 auto sl = std::make_unique< QgsSVGFillSymbolLayer >( path, size,
angle );
2454 sl->setOutputUnit( sldUnitSize );
2457 sl->setSvgStrokeWidth( strokeWidth );
2460 QDomElement strokeElem = element.firstChildElement( u
"Stroke"_s );
2461 if ( !strokeElem.isNull() )
2467 layers.append( l.release() );
2472 return sl.release();
2490 double width = mPatternWidth;
2496 QString svgFile = mSvgFilePath;
2515 double strokeWidth = mSvgStrokeWidth;
2524 mSvgStrokeWidthUnit, context, mPatternWidthMapUnitScale, mSvgStrokeWidthMapUnitScale, evaluatedParameters );
2528void QgsSVGFillSymbolLayer::storeViewBox()
2530 if ( !mSvgData.isEmpty() )
2532 QSvgRenderer r( mSvgData );
2535 mSvgViewBox = r.viewBoxF();
2540 mSvgViewBox = QRectF();
2543void QgsSVGFillSymbolLayer::setDefaultSvgParams()
2545 if ( mSvgFilePath.isEmpty() )
2550 bool hasFillParam, hasFillOpacityParam, hasStrokeParam, hasStrokeWidthParam, hasStrokeOpacityParam;
2551 bool hasDefaultFillColor, hasDefaultFillOpacity, hasDefaultStrokeColor, hasDefaultStrokeWidth, hasDefaultStrokeOpacity;
2552 QColor defaultFillColor, defaultStrokeColor;
2553 double defaultStrokeWidth, defaultFillOpacity, defaultStrokeOpacity;
2555 hasFillOpacityParam, hasDefaultFillOpacity, defaultFillOpacity,
2556 hasStrokeParam, hasDefaultStrokeColor, defaultStrokeColor,
2557 hasStrokeWidthParam, hasDefaultStrokeWidth, defaultStrokeWidth,
2558 hasStrokeOpacityParam, hasDefaultStrokeOpacity, defaultStrokeOpacity );
2560 double newFillOpacity = hasFillOpacityParam ?
mColor.alphaF() : 1.0;
2561 double newStrokeOpacity = hasStrokeOpacityParam ? mSvgStrokeColor.alphaF() : 1.0;
2563 if ( hasDefaultFillColor )
2565 mColor = defaultFillColor;
2566 mColor.setAlphaF( newFillOpacity );
2568 if ( hasDefaultFillOpacity )
2570 mColor.setAlphaF( defaultFillOpacity );
2572 if ( hasDefaultStrokeColor )
2574 mSvgStrokeColor = defaultStrokeColor;
2575 mSvgStrokeColor.setAlphaF( newStrokeOpacity );
2577 if ( hasDefaultStrokeOpacity )
2579 mSvgStrokeColor.setAlphaF( defaultStrokeOpacity );
2581 if ( hasDefaultStrokeWidth )
2583 mSvgStrokeWidth = defaultStrokeWidth;
2596 mFillLineSymbol = std::make_unique<QgsLineSymbol>( );
2604 mFillLineSymbol->setWidth( w );
2610 mFillLineSymbol->setColor(
c );
2616 return mFillLineSymbol ? mFillLineSymbol->color() :
mColor;
2628 mFillLineSymbol.reset( qgis::down_cast<QgsLineSymbol *>( symbol ) );
2637 return mFillLineSymbol.get();
2643 if ( mFillLineSymbol )
2644 attr.unite( mFillLineSymbol->usedAttributes( context ) );
2652 if ( mFillLineSymbol && mFillLineSymbol->hasDataDefinedProperties() )
2674 double lineAngleRad { qDegreesToRadians( mLineAngle ) };
2676 const int quadrant {
static_cast<int>( lineAngleRad / M_PI_2 ) };
2677 Q_ASSERT( quadrant >= 0 && quadrant <= 3 );
2687 lineAngleRad -= M_PI / 2;
2692 lineAngleRad -= M_PI;
2697 lineAngleRad -= M_PI + M_PI_2;
2705 QSize size {
static_cast<int>( distancePx ),
static_cast<int>( distancePx ) };
2707 if (
static_cast<int>( mLineAngle ) % 90 != 0 )
2709 size = QSize(
static_cast<int>( distancePx / std::sin( lineAngleRad ) ),
static_cast<int>( distancePx / std::cos( lineAngleRad ) ) );
2712 QPixmap pixmap( size );
2713 pixmap.fill( Qt::transparent );
2715 painter.begin( &pixmap );
2716 painter.setRenderHint( QPainter::Antialiasing );
2724 std::unique_ptr< QgsLinePatternFillSymbolLayer > layerClone(
clone() );
2725 layerClone->setOffset( 0 );
2726 layerClone->drawPreviewIcon( symbolContext, pixmap.size() );
2728 return pixmap.toImage();
2739 mDistanceUnit = unit;
2740 mLineWidthUnit = unit;
2743 if ( mFillLineSymbol )
2744 mFillLineSymbol->setOutputUnit( unit );
2767 mDistanceMapUnitScale = scale;
2768 mLineWidthMapUnitScale = scale;
2769 mOffsetMapUnitScale = scale;
2775 mDistanceMapUnitScale == mLineWidthMapUnitScale &&
2776 mLineWidthMapUnitScale == mOffsetMapUnitScale )
2778 return mDistanceMapUnitScale;
2785 auto patternLayer = std::make_unique< QgsLinePatternFillSymbolLayer >();
2791 QColor
color( Qt::black );
2799 else if (
properties.contains( u
"angle"_s ) )
2803 patternLayer->setLineAngle(
lineAngle );
2809 patternLayer->setDistance(
distance );
2816 else if (
properties.contains( u
"outline_width"_s ) )
2820 else if (
properties.contains( u
"line_width"_s ) )
2824 patternLayer->setLineWidth(
lineWidth );
2830 else if (
properties.contains( u
"outline_color"_s ) )
2834 else if (
properties.contains( u
"line_color"_s ) )
2838 patternLayer->setColor(
color );
2844 patternLayer->setOffset(
offset );
2847 if (
properties.contains( u
"distance_unit"_s ) )
2851 if (
properties.contains( u
"distance_map_unit_scale"_s ) )
2855 if (
properties.contains( u
"line_width_unit"_s ) )
2859 else if (
properties.contains( u
"outline_width_unit"_s ) )
2863 if (
properties.contains( u
"line_width_map_unit_scale"_s ) )
2867 if (
properties.contains( u
"offset_unit"_s ) )
2871 if (
properties.contains( u
"offset_map_unit_scale"_s ) )
2875 if (
properties.contains( u
"outline_width_unit"_s ) )
2879 if (
properties.contains( u
"outline_width_map_unit_scale"_s ) )
2883 if (
properties.contains( u
"coordinate_reference"_s ) )
2892 patternLayer->restoreOldDataDefinedProperties(
properties );
2894 return patternLayer.release();
2899 return u
"LinePatternFill"_s;
2902bool QgsLinePatternFillSymbolLayer::applyPattern(
const QgsSymbolRenderContext &context, QBrush &brush,
double lineAngle,
double distance )
2904 mBrush.setTextureImage( QImage() );
2906 if ( !mFillLineSymbol )
2911 std::unique_ptr< QgsLineSymbol > fillLineSymbol( mFillLineSymbol->clone() );
2912 if ( !fillLineSymbol )
2928 outputPixelOffset = std::fmod( outputPixelOffset, outputPixelDist );
2929 if ( outputPixelOffset > outputPixelDist / 2.0 )
2930 outputPixelOffset -= outputPixelDist;
2934 double outputPixelBleed = 0;
2935 double outputPixelInterval = 0;
2936 for (
int i = 0; i < fillLineSymbol->symbolLayerCount(); i++ )
2940 outputPixelBleed = std::max( outputPixelBleed, outputPixelLayerBleed );
2942 QgsMarkerLineSymbolLayer *markerLineLayer =
dynamic_cast<QgsMarkerLineSymbolLayer *
>( layer );
2943 if ( markerLineLayer )
2952 outputPixelInterval = std::max( outputPixelInterval, outputPixelLayerInterval );
2956 if ( outputPixelInterval > 0 )
2960 double intervalScale = std::round( outputPixelInterval ) / outputPixelInterval;
2961 outputPixelInterval = std::round( outputPixelInterval );
2963 for (
int i = 0; i < fillLineSymbol->symbolLayerCount(); i++ )
2967 QgsMarkerLineSymbolLayer *markerLineLayer =
dynamic_cast<QgsMarkerLineSymbolLayer *
>( layer );
2968 if ( markerLineLayer )
2982 height = outputPixelDist;
2983 width = outputPixelInterval > 0 ? outputPixelInterval : height;
2987 width = outputPixelDist;
2988 height = outputPixelInterval > 0 ? outputPixelInterval : width;
2992 height = outputPixelDist / std::cos(
lineAngle * M_PI / 180 );
2993 width = outputPixelDist / std::sin(
lineAngle * M_PI / 180 );
2996 lineAngle = 180 * std::atan2(
static_cast< double >( height ),
static_cast< double >( width ) ) / M_PI;
3002 height = std::abs( height );
3003 width = std::abs( width );
3005 outputPixelDist = std::abs( height * std::cos(
lineAngle * M_PI / 180 ) );
3009 int offsetHeight =
static_cast< int >( std::round( outputPixelOffset / std::cos(
lineAngle * M_PI / 180 ) ) );
3010 outputPixelOffset = offsetHeight * std::cos(
lineAngle * M_PI / 180 );
3019 int bufferMulti =
static_cast< int >( std::max( std::ceil( outputPixelBleed / width ), std::ceil( outputPixelBleed / width ) ) );
3023 bufferMulti = std::max( bufferMulti, 1 );
3025 int xBuffer = width * bufferMulti;
3026 int yBuffer = height * bufferMulti;
3027 int innerWidth = width;
3028 int innerHeight = height;
3029 width += 2 * xBuffer;
3030 height += 2 * yBuffer;
3033 if ( width > 2000 || height > 2000 || width == 0 || height == 0 )
3038 QImage patternImage( width, height, QImage::Format_ARGB32 );
3039 patternImage.fill( 0 );
3041 QPointF p1, p2, p3, p4, p5, p6;
3044 p1 = QPointF( 0, yBuffer );
3045 p2 = QPointF( width, yBuffer );
3046 p3 = QPointF( 0, yBuffer + innerHeight );
3047 p4 = QPointF( width, yBuffer + innerHeight );
3051 p1 = QPointF( xBuffer, height );
3052 p2 = QPointF( xBuffer, 0 );
3053 p3 = QPointF( xBuffer + innerWidth, height );
3054 p4 = QPointF( xBuffer + innerWidth, 0 );
3058 dx = outputPixelDist * std::cos( ( 90 -
lineAngle ) * M_PI / 180.0 );
3059 dy = outputPixelDist * std::sin( ( 90 -
lineAngle ) * M_PI / 180.0 );
3060 p1 = QPointF( 0, height );
3061 p2 = QPointF( width, 0 );
3062 p3 = QPointF( -dx, height - dy );
3063 p4 = QPointF( width - dx, -dy );
3064 p5 = QPointF( dx, height + dy );
3065 p6 = QPointF( width + dx, dy );
3069 dx = outputPixelDist * std::cos( ( 90 -
lineAngle ) * M_PI / 180.0 );
3070 dy = outputPixelDist * std::sin( ( 90 -
lineAngle ) * M_PI / 180.0 );
3071 p1 = QPointF( width, 0 );
3072 p2 = QPointF( 0, height );
3073 p3 = QPointF( width - dx, -dy );
3074 p4 = QPointF( -dx, height - dy );
3075 p5 = QPointF( width + dx, dy );
3076 p6 = QPointF( dx, height + dy );
3080 dy = outputPixelDist * std::cos( ( 180 -
lineAngle ) * M_PI / 180 );
3081 dx = outputPixelDist * std::sin( ( 180 -
lineAngle ) * M_PI / 180 );
3082 p1 = QPointF( 0, 0 );
3083 p2 = QPointF( width, height );
3084 p5 = QPointF( dx, -dy );
3085 p6 = QPointF( width + dx, height - dy );
3086 p3 = QPointF( -dx, dy );
3087 p4 = QPointF( width - dx, height + dy );
3091 dy = outputPixelDist * std::cos( ( 180 -
lineAngle ) * M_PI / 180 );
3092 dx = outputPixelDist * std::sin( ( 180 -
lineAngle ) * M_PI / 180 );
3093 p1 = QPointF( width, height );
3094 p2 = QPointF( 0, 0 );
3095 p5 = QPointF( width + dx, height - dy );
3096 p6 = QPointF( dx, -dy );
3097 p3 = QPointF( width - dx, height + dy );
3098 p4 = QPointF( -dx, dy );
3105 p3 = QPointF( tempPt.x(), tempPt.y() );
3107 p4 = QPointF( tempPt.x(), tempPt.y() );
3109 p5 = QPointF( tempPt.x(), tempPt.y() );
3111 p6 = QPointF( tempPt.x(), tempPt.y() );
3115 p1 = QPointF( tempPt.x(), tempPt.y() );
3117 p2 = QPointF( tempPt.x(), tempPt.y() );
3120 QPainter p( &patternImage );
3124 p.setRenderHint( QPainter::Antialiasing,
false );
3125 QPen pen( QColor( Qt::black ) );
3126 pen.setWidthF( 0.1 );
3127 pen.setCapStyle( Qt::FlatCap );
3132 QPolygon polygon = QPolygon() << QPoint( 0, 0 ) << QPoint( width - 1, 0 ) << QPoint( width - 1, height - 1 ) << QPoint( 0, height - 1 ) << QPoint( 0, 0 );
3133 p.drawPolygon( polygon );
3135 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 );
3136 p.drawPolygon( polygon );
3142 p.setRenderHint( QPainter::Antialiasing,
true );
3145 QgsRenderContext lineRenderContext;
3155 fillLineSymbol->startRender( lineRenderContext, context.
fields() );
3157 QVector<QPolygonF> polygons;
3158 polygons.append( QPolygonF() << p1 << p2 );
3159 polygons.append( QPolygonF() << p3 << p4 );
3162 polygons.append( QPolygonF() << p5 << p6 );
3166 for (
const QPolygonF &polygon : std::as_const( polygons ) )
3168 fillLineSymbol->renderPolyline( polygon, context.
feature(), lineRenderContext, -1, useSelectedColor );
3171 fillLineSymbol->stopRender( lineRenderContext );
3175 patternImage = patternImage.copy( xBuffer, yBuffer, patternImage.width() - 2 * xBuffer, patternImage.height() - 2 * yBuffer );
3180 QImage transparentImage = patternImage.copy();
3182 brush.setTextureImage( transparentImage );
3186 brush.setTextureImage( patternImage );
3189 QTransform brushTransform;
3190 brush.setTransform( brushTransform );
3200 || ( mFillLineSymbol && mFillLineSymbol->hasDataDefinedProperties() )
3204 if ( !mRenderUsingLines )
3208 mRenderUsingLines = !applyPattern( context,
mBrush, mLineAngle, mDistance );
3211 if ( mRenderUsingLines && mFillLineSymbol )
3215 mFillLineSymbolRenderStarted =
true;
3221 if ( mFillLineSymbolRenderStarted )
3224 mFillLineSymbolRenderStarted =
false;
3231 if ( !useSelectedColor && !mRenderUsingLines )
3238 if ( !mFillLineSymbol )
3241 if ( !mFillLineSymbolRenderStarted )
3245 mFillLineSymbolRenderStarted =
true;
3276 outputPixelOffset = std::fmod( outputPixelOffset, outputPixelDistance );
3277 if ( outputPixelOffset > outputPixelDistance / 2.0 )
3278 outputPixelOffset -= outputPixelDistance;
3280 p->setPen( QPen( Qt::NoPen ) );
3287 outputPixelDistance = std::max(
3291 outputPixelDistance );
3309 std::unique_ptr< QgsPolygon > shapePolygon;
3310 std::unique_ptr< QgsGeometryEngine > shapeEngine;
3318 shapePolygon = std::make_unique< QgsPolygon >();
3320 shapePolygon->setExteriorRing( fromPolygon.release() );
3323 for (
const QPolygonF &ring : *rings )
3326 shapePolygon->addInteriorRing( fromRing.release() );
3330 shapeEngine->prepareGeometry();
3337 path.addPolygon( points );
3340 for (
const QPolygonF &ring : *rings )
3342 path.addPolygon( ring );
3345 p->setClipPath( path, Qt::IntersectClip );
3351 const QRectF boundingRect = points.boundingRect();
3353 QTransform invertedRotateTransform;
3359 QTransform transform;
3360 if ( applyBrushTransform )
3363 transform.translate( -boundingRect.center().x(),
3364 -boundingRect.center().y() );
3366 transform.translate( boundingRect.center().x(),
3367 boundingRect.center().y() );
3375 const QRectF transformedBounds = transform.map( points ).boundingRect();
3379 left = transformedBounds.left() - buffer * 2;
3380 top = transformedBounds.top() - buffer * 2;
3381 right = transformedBounds.right() + buffer * 2;
3382 bottom = transformedBounds.bottom() + buffer * 2;
3383 invertedRotateTransform = transform.inverted();
3385 if ( !applyBrushTransform )
3387 top -= transformedBounds.top() - ( outputPixelDistance * std::floor( transformedBounds.top() / outputPixelDistance ) );
3392 const bool needsExpressionContext = mFillLineSymbol->hasDataDefinedProperties();
3397 int currentLine = 0;
3398 for (
double currentY = top; currentY <= bottom; currentY += outputPixelDistance )
3403 if ( needsExpressionContext )
3407 double y1 = currentY;
3409 double y2 = currentY;
3410 invertedRotateTransform.map( left, currentY - outputPixelOffset, &x1, &y1 );
3411 invertedRotateTransform.map( right, currentY - outputPixelOffset, &x2, &y2 );
3416 std::unique_ptr< QgsAbstractGeometry > intersection( shapeEngine->intersection( &ls ) );
3417 for (
auto it = intersection->const_parts_begin(); it != intersection->const_parts_end(); ++it )
3427 mFillLineSymbol->renderPolyline( QPolygonF() << QPointF( x1, y1 ) << QPointF( x2, y2 ), context.
feature(), context.
renderContext(), -1, useSelectedColor );
3439 map.insert( u
"angle"_s, QString::number( mLineAngle ) );
3440 map.insert( u
"distance"_s, QString::number( mDistance ) );
3441 map.insert( u
"line_width"_s, QString::number( mLineWidth ) );
3443 map.insert( u
"offset"_s, QString::number( mOffset ) );
3459 if ( mFillLineSymbol )
3472 toSld( doc, element, context );
3478 QDomElement symbolizerElem = doc.createElement( u
"se:PolygonSymbolizer"_s );
3479 if ( !props.value( u
"uom"_s, QString() ).toString().isEmpty() )
3480 symbolizerElem.setAttribute( u
"uom"_s, props.value( u
"uom"_s, QString() ).toString() );
3481 element.appendChild( symbolizerElem );
3486 QDomElement fillElem = doc.createElement( u
"se:Fill"_s );
3487 symbolizerElem.appendChild( fillElem );
3489 QDomElement graphicFillElem = doc.createElement( u
"se:GraphicFill"_s );
3490 fillElem.appendChild( graphicFillElem );
3492 QDomElement graphicElem = doc.createElement( u
"se:Graphic"_s );
3493 graphicFillElem.appendChild( graphicElem );
3496 bool exportOk {
false };
3500 if ( ! image.isNull() )
3503 QString pngPath { info.completeSuffix().isEmpty() ? context.
exportFilePath() : context.
exportFilePath().chopped( info.completeSuffix().length() ).append( u
"png"_s ) };
3504 pngPath = QgsFileUtils::uniquePath( pngPath );
3505 image.save( pngPath );
3514 QColor lineColor = mFillLineSymbol ? mFillLineSymbol->color() : QColor();
3515 double lineWidth = mFillLineSymbol ? mFillLineSymbol->width() : 0.0;
3523 double angle = props.value( u
"angle"_s, u
"0"_s ).toDouble( &ok );
3526 angleFunc = u
"%1 + %2"_s.arg( props.value( u
"angle"_s, u
"0"_s ).toString() ).arg( mLineAngle );
3530 angleFunc = QString::number(
angle + mLineAngle );
3535 QPointF lineOffset( std::sin( mLineAngle ) * mOffset, std::cos( mLineAngle ) * mOffset );
3544 QString featureStyle;
3545 featureStyle.append(
"Brush(" );
3546 featureStyle.append( u
"fc:%1"_s.arg(
mColor.name() ) );
3547 featureStyle.append( u
",bc:%1"_s.arg(
"#00000000"_L1 ) );
3548 featureStyle.append(
",id:\"ogr-brush-2\"" );
3549 featureStyle.append( u
",a:%1"_s.arg( mLineAngle ) );
3550 featureStyle.append( u
",s:%1"_s.arg( mLineWidth * widthScaleFactor ) );
3551 featureStyle.append(
",dx:0mm" );
3552 featureStyle.append( u
",dy:%1mm"_s.arg( mDistance * widthScaleFactor ) );
3553 featureStyle.append(
')' );
3554 return featureStyle;
3560 && ( !mFillLineSymbol || !mFillLineSymbol->hasDataDefinedProperties() ) )
3585 Qt::PenStyle lineStyle;
3587 QDomElement fillElem = element.firstChildElement( u
"Fill"_s );
3588 if ( fillElem.isNull() )
3591 QDomElement graphicFillElem = fillElem.firstChildElement( u
"GraphicFill"_s );
3592 if ( graphicFillElem.isNull() )
3595 QDomElement graphicElem = graphicFillElem.firstChildElement( u
"Graphic"_s );
3596 if ( graphicElem.isNull() )
3602 if ( name !=
"horline"_L1 )
3610 double d = angleFunc.toDouble( &ok );
3619 offset = std::sqrt( std::pow( vectOffset.x(), 2 ) + std::pow( vectOffset.y(), 2 ) );
3622 double scaleFactor = 1.0;
3623 const QString uom = element.attribute( u
"uom"_s );
3625 size = size * scaleFactor;
3628 auto sl = std::make_unique< QgsLinePatternFillSymbolLayer >();
3629 sl->setOutputUnit( sldUnitSize );
3630 sl->setColor( lineColor );
3632 sl->setLineAngle(
angle );
3634 sl->setDistance( size );
3637 QDomElement strokeElem = element.firstChildElement( u
"Stroke"_s );
3638 if ( !strokeElem.isNull() )
3644 layers.append( l.release() );
3649 return sl.release();
3749 auto layer = std::make_unique< QgsPointPatternFillSymbolLayer >();
3750 if (
properties.contains( u
"distance_x"_s ) )
3752 layer->setDistanceX(
properties[u
"distance_x"_s].toDouble() );
3754 if (
properties.contains( u
"distance_y"_s ) )
3756 layer->setDistanceY(
properties[u
"distance_y"_s].toDouble() );
3758 if (
properties.contains( u
"displacement_x"_s ) )
3760 layer->setDisplacementX(
properties[u
"displacement_x"_s].toDouble() );
3762 if (
properties.contains( u
"displacement_y"_s ) )
3764 layer->setDisplacementY(
properties[u
"displacement_y"_s].toDouble() );
3768 layer->setOffsetX(
properties[u
"offset_x"_s].toDouble() );
3772 layer->setOffsetY(
properties[u
"offset_y"_s].toDouble() );
3775 if (
properties.contains( u
"distance_x_unit"_s ) )
3779 if (
properties.contains( u
"distance_x_map_unit_scale"_s ) )
3783 if (
properties.contains( u
"distance_y_unit"_s ) )
3787 if (
properties.contains( u
"distance_y_map_unit_scale"_s ) )
3791 if (
properties.contains( u
"displacement_x_unit"_s ) )
3795 if (
properties.contains( u
"displacement_x_map_unit_scale"_s ) )
3799 if (
properties.contains( u
"displacement_y_unit"_s ) )
3803 if (
properties.contains( u
"displacement_y_map_unit_scale"_s ) )
3807 if (
properties.contains( u
"offset_x_unit"_s ) )
3811 if (
properties.contains( u
"offset_x_map_unit_scale"_s ) )
3815 if (
properties.contains( u
"offset_y_unit"_s ) )
3819 if (
properties.contains( u
"offset_y_map_unit_scale"_s ) )
3824 if (
properties.contains( u
"random_deviation_x"_s ) )
3826 layer->setMaximumRandomDeviationX(
properties[u
"random_deviation_x"_s].toDouble() );
3828 if (
properties.contains( u
"random_deviation_y"_s ) )
3830 layer->setMaximumRandomDeviationY(
properties[u
"random_deviation_y"_s].toDouble() );
3832 if (
properties.contains( u
"random_deviation_x_unit"_s ) )
3836 if (
properties.contains( u
"random_deviation_x_map_unit_scale"_s ) )
3840 if (
properties.contains( u
"random_deviation_y_unit"_s ) )
3844 if (
properties.contains( u
"random_deviation_y_map_unit_scale"_s ) )
3848 unsigned long seed = 0;
3855 std::random_device rd;
3856 std::mt19937 mt(
static_cast< int >( rd() ) );
3857 std::uniform_int_distribution<> uniformDist( 1, 999999999 );
3858 seed = uniformDist( mt );
3860 layer->setSeed(
seed );
3862 if (
properties.contains( u
"outline_width_unit"_s ) )
3866 if (
properties.contains( u
"outline_width_map_unit_scale"_s ) )
3874 if (
properties.contains( u
"coordinate_reference"_s ) )
3881 layer->setAngle(
properties[u
"angle"_s].toDouble() );
3886 return layer.release();
3891 return u
"PointPatternFill"_s;
3894bool QgsPointPatternFillSymbolLayer::applyPattern(
const QgsSymbolRenderContext &context, QBrush &brush,
double distanceX,
double distanceY,
3895 double displacementX,
double displacementY,
double offsetX,
double offsetY )
3902 double widthOffset = std::fmod(
3905 double heightOffset = std::fmod(
3909 if ( width > 2000 || height > 2000 )
3911 brush.setTextureImage( QImage() );
3915 QImage patternImage( width, height, QImage::Format_ARGB32 );
3916 patternImage.fill( 0 );
3917 if ( patternImage.isNull() )
3919 brush.setTextureImage( QImage() );
3924 QPainter p( &patternImage );
3927 QgsRenderContext pointRenderContext;
3942 for (
double currentX = -width; currentX <= width * 2.0; currentX += width )
3944 for (
double currentY = -height; currentY <= height * 2.0; currentY += height )
3946 mMarkerSymbol->renderPoint( QPointF( currentX + widthOffset, currentY + heightOffset ), context.
feature(), pointRenderContext );
3957 for (
double currentX = -width; currentX <= width * 2.0; currentX += width )
3959 for (
double currentY = -height / 2.0; currentY <= height * 2.0; currentY += height )
3961 mMarkerSymbol->renderPoint( QPointF( currentX + widthOffset + displacementPixelX, currentY + heightOffset ), context.
feature(), pointRenderContext );
3965 for (
double currentX = -width / 2.0; currentX <= width * 2.0; currentX += width )
3967 for (
double currentY = -height; currentY <= height * 2.0; currentY += height / 2.0 )
3969 mMarkerSymbol->renderPoint( QPointF( currentX + widthOffset + ( std::fmod( currentY, height ) != 0 ? displacementPixelX : 0 ), currentY + heightOffset - displacementPixelY ), context.
feature(), pointRenderContext );
3978 QImage transparentImage = patternImage.copy();
3980 brush.setTextureImage( transparentImage );
3984 brush.setTextureImage( patternImage );
3986 QTransform brushTransform;
3987 brush.setTransform( brushTransform );
4007 if ( !mRenderUsingMarkers )
4052 if ( !useSelectedColor && !mRenderUsingMarkers )
4102 const double widthOffset = std::fmod(
4114 const double heightOffset = std::fmod(
4140 p->setPen( QPen( Qt::NoPen ) );
4172 std::unique_ptr< QgsPolygon > shapePolygon;
4173 std::unique_ptr< QgsGeometryEngine > shapeEngine;
4180 shapePolygon = std::make_unique< QgsPolygon >();
4182 shapePolygon->setExteriorRing( fromPolygon.release() );
4185 for (
const QPolygonF &ring : *rings )
4188 shapePolygon->addInteriorRing( fromRing.release() );
4192 shapeEngine->prepareGeometry();
4199 path.addPolygon( points );
4202 for (
const QPolygonF &ring : *rings )
4204 path.addPolygon( ring );
4207 p->setClipPath( path, Qt::IntersectClip );
4213 const QRectF boundingRect = points.boundingRect();
4215 QTransform invertedRotateTransform;
4223 QTransform transform;
4224 if ( applyBrushTransform )
4227 transform.translate( -boundingRect.center().x(),
4228 -boundingRect.center().y() );
4229 transform.rotate( -
angle );
4230 transform.translate( boundingRect.center().x(),
4231 boundingRect.center().y() );
4236 transform.rotate( -
angle );
4239 const QRectF transformedBounds = transform.map( points ).boundingRect();
4240 left = transformedBounds.left() - 2 * width;
4241 top = transformedBounds.top() - 2 * height;
4242 right = transformedBounds.right() + 2 * width;
4243 bottom = transformedBounds.bottom() + 2 * height;
4244 invertedRotateTransform = transform.inverted();
4246 if ( !applyBrushTransform )
4248 left -= transformedBounds.left() - ( width * std::floor( transformedBounds.left() / width ) );
4249 top -= transformedBounds.top() - ( height * std::floor( transformedBounds.top() / height ) );
4254 left = boundingRect.left() - 2 * width;
4255 top = boundingRect.top() - 2 * height;
4256 right = boundingRect.right() + 2 * width;
4257 bottom = boundingRect.bottom() + 2 * height;
4259 if ( !applyBrushTransform )
4261 left -= boundingRect.left() - ( width * std::floor( boundingRect.left() / width ) );
4262 top -= boundingRect.top() - ( height * std::floor( boundingRect.top() / height ) );
4291 std::random_device rd;
4292 std::mt19937 mt(
seed == 0 ? rd() :
seed );
4293 std::uniform_real_distribution<> uniformDist( 0, 1 );
4299 const bool needsExpressionContext =
mMarkerSymbol->hasDataDefinedProperties();
4307 bool alternateColumn =
false;
4308 int currentCol = -3;
4309 for (
double currentX = left; currentX <= right; currentX += width, alternateColumn = !alternateColumn )
4314 if ( needsExpressionContext )
4317 bool alternateRow =
false;
4318 const double columnX = currentX + widthOffset;
4319 int currentRow = -3;
4320 for (
double currentY = top; currentY <= bottom; currentY += height, alternateRow = !alternateRow )
4325 double y = currentY + heightOffset;
4328 x += displacementPixelX;
4330 if ( !alternateColumn )
4331 y -= displacementPixelY;
4337 invertedRotateTransform.map( xx, yy, &x, &y );
4340 if ( useRandomShift )
4342 x += ( 2 * uniformDist( mt ) - 1 ) * maxRandomDeviationPixelX;
4343 y += ( 2 * uniformDist( mt ) - 1 ) * maxRandomDeviationPixelY;
4346 if ( needsExpressionContext )
4354 bool renderPoint =
true;
4362 renderPoint = shapeEngine->intersects( &p );
4372 renderPoint = shapeEngine->contains( markerBounds.
constGet() );
4374 renderPoint = shapeEngine->intersects( markerBounds.
constGet() );
4400 map.insert( u
"distance_x"_s, QString::number(
mDistanceX ) );
4401 map.insert( u
"distance_y"_s, QString::number(
mDistanceY ) );
4402 map.insert( u
"displacement_x"_s, QString::number(
mDisplacementX ) );
4403 map.insert( u
"displacement_y"_s, QString::number(
mDisplacementY ) );
4404 map.insert( u
"offset_x"_s, QString::number(
mOffsetX ) );
4405 map.insert( u
"offset_y"_s, QString::number(
mOffsetY ) );
4427 map.insert( u
"seed"_s, QString::number(
mSeed ) );
4428 map.insert( u
"angle"_s,
mAngle );
4449 toSld( doc, element, context );
4455 for (
int symbolLayerIdx = 0; symbolLayerIdx <
mMarkerSymbol->symbolLayerCount(); symbolLayerIdx++ )
4457 QDomElement symbolizerElem = doc.createElement( u
"se:PolygonSymbolizer"_s );
4458 if ( !props.value( u
"uom"_s, QString() ).toString().isEmpty() )
4459 symbolizerElem.setAttribute( u
"uom"_s, props.value( u
"uom"_s, QString() ).toString() );
4460 element.appendChild( symbolizerElem );
4465 QDomElement fillElem = doc.createElement( u
"se:Fill"_s );
4466 symbolizerElem.appendChild( fillElem );
4468 QDomElement graphicFillElem = doc.createElement( u
"se:GraphicFill"_s );
4469 fillElem.appendChild( graphicFillElem );
4474 bool exportOk {
false };
4478 if ( ! image.isNull() )
4480 QDomElement graphicElem = doc.createElement( u
"se:Graphic"_s );
4481 graphicFillElem.appendChild( graphicElem );
4483 QString pngPath { info.completeSuffix().isEmpty() ? context.
exportFilePath() : context.
exportFilePath().chopped( info.completeSuffix().length() ).append( u
"png"_s ) };
4484 pngPath = QgsFileUtils::uniquePath( pngPath );
4485 image.save( pngPath );
4504 symbolizerElem.appendChild( graphicMarginElem );
4508 markerLayer->writeSldMarker( doc, graphicFillElem, context );
4516 QgsDebugError( u
"Missing point pattern symbol layer. Skip it."_s );
4526 double angleRads { qDegreesToRadians(
mAngle ) };
4535 if ( displacementXPx != 0 )
4540 if ( displacementYPx != 0 )
4547 QPixmap pixmap( size );
4548 pixmap.fill( Qt::transparent );
4550 painter.begin( &pixmap );
4551 painter.setRenderHint( QPainter::Antialiasing );
4559 std::unique_ptr< QgsPointPatternFillSymbolLayer > layerClone(
clone() );
4561 layerClone->setAngle( qRadiansToDegrees( angleRads ) );
4564 layerClone->setMaximumRandomDeviationX( 0 );
4565 layerClone->setMaximumRandomDeviationY( 0 );
4567 layerClone->drawPreviewIcon( symbolContext, pixmap.size() );
4569 return pixmap.toImage();
4577 QDomElement fillElem = element.firstChildElement( u
"Fill"_s );
4578 if ( fillElem.isNull() )
4581 QDomElement graphicFillElem = fillElem.firstChildElement( u
"GraphicFill"_s );
4582 if ( graphicFillElem.isNull() )
4585 QDomElement graphicElem = graphicFillElem.firstChildElement( u
"Graphic"_s );
4586 if ( graphicElem.isNull() )
4590 if ( !simpleMarkerSl )
4594 layers.append( simpleMarkerSl.release() );
4596 auto marker = std::make_unique< QgsMarkerSymbol >( layers );
4599 const double markerSize { marker->size() };
4601 auto pointPatternFillSl = std::make_unique< QgsPointPatternFillSymbolLayer >();
4602 pointPatternFillSl->setSubSymbol( marker.release() );
4607 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.release();
4798 attributes.unite(
mMarkerSymbol->usedAttributes( context ) );
4836 auto sl = std::make_unique< QgsCentroidFillSymbolLayer >();
4838 if (
properties.contains( u
"point_on_surface"_s ) )
4839 sl->setPointOnSurface(
properties[u
"point_on_surface"_s].toInt() != 0 );
4840 if (
properties.contains( u
"point_on_all_parts"_s ) )
4841 sl->setPointOnAllParts(
properties[u
"point_on_all_parts"_s].toInt() != 0 );
4842 if (
properties.contains( u
"clip_points"_s ) )
4843 sl->setClipPoints(
properties[u
"clip_points"_s].toInt() != 0 );
4844 if (
properties.contains( u
"clip_on_current_part_only"_s ) )
4845 sl->setClipOnCurrentPartOnly(
properties[u
"clip_on_current_part_only"_s].toInt() != 0 );
4847 sl->restoreOldDataDefinedProperties(
properties );
4849 return sl.release();
4854 return u
"CentroidFill"_s;
4882 part.exterior = points;
4884 part.rings = *rings;
4892 mCurrentParts << part;
4897 const double prevOpacity =
mMarker->opacity();
4901 mMarker->setOpacity( prevOpacity );
4910 mCurrentParts.clear();
4917 const double prevOpacity =
mMarker->opacity();
4923 mMarker->setOpacity( prevOpacity );
4928void QgsCentroidFillSymbolLayer::render(
QgsRenderContext &context,
const QVector<QgsCentroidFillSymbolLayer::Part> &parts,
const QgsFeature &feature,
bool selected )
4937 QVector< QgsGeometry > geometryParts;
4938 geometryParts.reserve( parts.size() );
4939 QPainterPath globalPath;
4942 int maxAreaPartIdx = 0;
4944 for (
int i = 0; i < parts.size(); i++ )
4946 const Part part = parts[i];
4949 if ( !geom.
isNull() && !part.rings.empty() )
4955 int area = poly->
area();
4957 if ( area > maxArea )
4967 globalPath.addPolygon( part.exterior );
4968 for (
const QPolygonF &ring : part.rings )
4970 globalPath.addPolygon( ring );
4975 for (
int i = 0; i < parts.size(); i++ )
4980 const Part part = parts[i];
4988 path.addPolygon( part.exterior );
4989 for (
const QPolygonF &ring : part.rings )
4991 path.addPolygon( ring );
5000 context.
painter()->setClipPath( path );
5007 mMarker->renderPoint( centroid, feature.
isValid() ? &feature :
nullptr, context, -1, selected );
5022 map[u
"clip_points"_s] = QString::number(
mClipPoints );
5029 auto x = std::make_unique< QgsCentroidFillSymbolLayer >();
5032 x->setSubSymbol(
mMarker->clone() );
5046 toSld( doc, element, context );
5054 return mMarker->toSld( doc, element, context );
5064 layers.append( l.release() );
5065 auto marker = std::make_unique<QgsMarkerSymbol>( layers );
5067 auto sl = std::make_unique< QgsCentroidFillSymbolLayer >();
5068 sl->setSubSymbol( marker.release() );
5069 sl->setPointOnAllParts(
false );
5070 return sl.release();
5097 attributes.unite(
mMarker->usedAttributes( context ) );
5120 mMarker->setOutputUnit( unit );
5137 return mMarker->usesMapUnits();
5146 mMarker->setMapUnitScale( scale );
5154 return mMarker->mapUnitScale();
5183 imagePath =
properties[u
"imageFile"_s].toString();
5185 if (
properties.contains( u
"coordinate_mode"_s ) )
5205 auto symbolLayer = std::make_unique< QgsRasterFillSymbolLayer >( imagePath );
5206 symbolLayer->setCoordinateMode( mode );
5207 symbolLayer->setOpacity( alpha );
5208 symbolLayer->setOffset(
offset );
5209 symbolLayer->setAngle(
angle );
5210 symbolLayer->setWidth(
width );
5211 if (
properties.contains( u
"offset_unit"_s ) )
5215 if (
properties.contains( u
"offset_map_unit_scale"_s ) )
5219 if (
properties.contains( u
"width_unit"_s ) )
5223 if (
properties.contains( u
"width_map_unit_scale"_s ) )
5230 symbolLayer->setHeight(
properties[u
"height"_s].toDouble() );
5233 symbolLayer->restoreOldDataDefinedProperties(
properties );
5235 return symbolLayer.release();
5240 QDomElement fillElem = element.firstChildElement( u
"Fill"_s );
5241 if ( fillElem.isNull() )
5244 QDomElement graphicFillElem = fillElem.firstChildElement( u
"GraphicFill"_s );
5245 if ( graphicFillElem.isNull() )
5248 QDomElement graphicElem = graphicFillElem.firstChildElement( u
"Graphic"_s );
5249 if ( graphicElem.isNull() )
5252 QString path, mimeType;
5260 if ( ! QFile::exists( path ) )
5265 auto sl = std::make_unique< QgsRasterFillSymbolLayer>( path );
5267 return sl.release();
5272 QVariantMap::iterator it =
properties.find( u
"imageFile"_s );
5276 it.value() = pathResolver.
writePath( it.value().toString() );
5278 it.value() = pathResolver.
readPath( it.value().toString() );
5290 return u
"RasterFill"_s;
5306 QPointF
offset = mOffset;
5324 QRectF boundingRect = points.boundingRect();
5325 mBrush.setTransform(
mBrush.transform().translate( boundingRect.left() -
mBrush.transform().dx(),
5326 boundingRect.top() -
mBrush.transform().dy() ) );
5338 applyPattern(
mBrush, mImageFilePath, mWidth, mHeight, mOpacity * context.
opacity(), context );
5349 map[u
"imageFile"_s] = mImageFilePath;
5350 map[u
"coordinate_mode"_s] = QString::number(
static_cast< int >( mCoordinateMode ) );
5351 map[u
"alpha"_s] = QString::number( mOpacity );
5355 map[u
"angle"_s] = QString::number(
mAngle );
5357 map[u
"width"_s] = QString::number( mWidth );
5358 map[u
"height"_s] = QString::number( mHeight );
5367 auto sl = std::make_unique< QgsRasterFillSymbolLayer >( mImageFilePath );
5368 sl->setCoordinateMode( mCoordinateMode );
5369 sl->setOpacity( mOpacity );
5370 sl->setOffset( mOffset );
5371 sl->setOffsetUnit( mOffsetUnit );
5372 sl->setOffsetMapUnitScale( mOffsetMapUnitScale );
5374 sl->setWidth( mWidth );
5375 sl->setHeight( mHeight );
5376 sl->setSizeUnit( mSizeUnit );
5377 sl->setSizeMapUnitScale( mSizeMapUnitScale );
5381 return sl.release();
5386 return context.
convertToPainterUnits( std::max( std::fabs( mOffset.x() ), std::fabs( mOffset.y() ) ), mOffsetUnit, mOffsetMapUnitScale );
5409 mImageFilePath = imagePath;
5414 mCoordinateMode = mode;
5433 if ( !hasWidthExpression && !hasHeightExpression && !hasAngleExpression && !hasOpacityExpression && !hasFileExpression )
5439 if ( hasAngleExpression )
5447 if ( !hasWidthExpression && !hasHeightExpression && !hasOpacityExpression && !hasFileExpression )
5452 double width = mWidth;
5453 if ( hasWidthExpression )
5459 if ( hasHeightExpression )
5465 if ( hasOpacityExpression )
5470 QString file = mImageFilePath;
5471 if ( hasFileExpression )
5484void QgsRasterFillSymbolLayer::applyPattern( QBrush &brush,
const QString &imageFilePath,
const double width,
const double height,
const double alpha,
const QgsSymbolRenderContext &context )
5486 double imageWidth = 0;
5487 double imageHeight = 0;
5502 if ( originalSize.isEmpty() )
5505 imageWidth = (
width * originalSize.width() ) / 100.0;
5508 if (
static_cast< int >( imageWidth ) < 1 || 10000.0 < imageWidth )
5521 if ( !originalSize.isValid() )
5524 if ( originalSize.isEmpty() )
5527 imageHeight = (
height * originalSize.height() ) / 100.0;
5530 if (
static_cast< int >( imageHeight ) < 1 || 10000.0 < imageHeight )
5535 if (
width == 0 && imageHeight > 0 )
5537 if ( !originalSize.isValid() )
5540 imageWidth = imageHeight * originalSize.width() / originalSize.height();
5542 else if (
height == 0 && imageWidth > 0 )
5544 if ( !originalSize.isValid() )
5547 imageHeight = imageWidth * originalSize.height() / originalSize.width();
5549 if ( imageWidth == 0 || imageHeight == 0 )
5551 if ( !originalSize.isValid() )
5554 imageWidth = originalSize.width();
5555 imageHeight = originalSize.height();
5563 brush.setTextureImage( img );
5572 : mCountMethod( method )
5588 unsigned long seed = 0;
5595 std::random_device rd;
5596 std::mt19937 mt(
static_cast< int >( rd() ) );
5597 std::uniform_int_distribution<> uniformDist( 1, 999999999 );
5598 seed = uniformDist( mt );
5603 if (
properties.contains( u
"density_area_unit"_s ) )
5605 if (
properties.contains( u
"density_area_unit_scale"_s ) )
5608 if (
properties.contains( u
"clip_points"_s ) )
5610 sl->setClipPoints(
properties[u
"clip_points"_s].toInt() );
5613 return sl.release();
5618 return u
"RandomMarkerFill"_s;
5623 mMarker->setColor(
color );
5629 return mMarker ? mMarker->color() :
mColor;
5646 part.exterior = points;
5648 part.rings = *rings;
5650 if ( mRenderingFeature )
5654 mFeatureSymbolOpacity = context.
opacity();
5655 mCurrentParts << part;
5660 const double prevOpacity = mMarker->opacity();
5661 mMarker->setOpacity( mMarker->opacity() * context.
opacity() );
5664 mMarker->setOpacity( prevOpacity );
5668void QgsRandomMarkerFillSymbolLayer::render(
QgsRenderContext &context,
const QVector<QgsRandomMarkerFillSymbolLayer::Part> &parts,
const QgsFeature &feature,
bool selected )
5677 QVector< QgsGeometry > geometryParts;
5678 geometryParts.reserve( parts.size() );
5681 for (
const Part &part : parts )
5684 if ( !geom.
isNull() && !part.rings.empty() )
5687 for (
const QPolygonF &ring : part.rings )
5695 geom = geom.
buffer( 0, 0 );
5697 geometryParts << geom;
5701 path.addPolygon( part.exterior );
5702 for (
const QPolygonF &ring : part.rings )
5704 path.addPolygon( ring );
5709 const QgsGeometry geom = geometryParts.count() != 1 ?
QgsGeometry::unaryUnion( geometryParts ) : geometryParts.at( 0 );
5714 context.
painter()->setClipPath( path );
5718 int count = mPointCount;
5721 context.expressionContext().setOriginalValueVariable( count );
5722 count = mDataDefinedProperties.valueAsInt( QgsSymbolLayer::Property::PointCount, context.expressionContext(), count );
5725 switch ( mCountMethod )
5737 count = std::max( 0.0, std::ceil( count * ( geom.
area() /
densityArea ) ) );
5744 unsigned long seed = mSeed;
5747 context.expressionContext().setOriginalValueVariable( static_cast< unsigned long long >( seed ) );
5748 seed = mDataDefinedProperties.valueAsInt( QgsSymbolLayer::Property::RandomSeed, context.expressionContext(), seed );
5755 std::sort( randomPoints.begin(), randomPoints.end(), [](
const QgsPointXY & a,
const QgsPointXY & b )->bool
5757 return a.y() < b.y();
5760 QgsExpressionContextScope *scope =
new QgsExpressionContextScope();
5761 QgsExpressionContextScopePopper scopePopper( context.
expressionContext(), scope );
5763 const bool needsExpressionContext = mMarker->hasDataDefinedProperties();
5768 for (
const QgsPointXY &p : std::as_const( randomPoints ) )
5770 if ( needsExpressionContext )
5772 mMarker->renderPoint( QPointF( p.x(), p.y() ), feature.
isValid() ? &feature :
nullptr, context, -1, selected );
5786 map.insert( u
"count_method"_s, QString::number(
static_cast< int >( mCountMethod ) ) );
5787 map.insert( u
"point_count"_s, QString::number( mPointCount ) );
5788 map.insert( u
"density_area"_s, QString::number( mDensityArea ) );
5791 map.insert( u
"seed"_s, QString::number( mSeed ) );
5792 map.insert( u
"clip_points"_s, QString::number( mClipPoints ) );
5798 auto res = std::make_unique< QgsRandomMarkerFillSymbolLayer >( mPointCount, mCountMethod, mDensityArea, mSeed );
5801 res->setDensityAreaUnit( mDensityAreaUnit );
5802 res->setDensityAreaUnitScale( mDensityAreaUnitScale );
5803 res->mClipPoints = mClipPoints;
5804 res->setSubSymbol( mMarker->clone() );
5807 return res.release();
5830 return mMarker.get();
5842 mColor = mMarker->color();
5851 attributes.unite( mMarker->usedAttributes( context ) );
5860 if ( mMarker && mMarker->hasDataDefinedProperties() )
5897 return mCountMethod;
5902 mCountMethod = method;
5907 return mDensityArea;
5912 mDensityArea = area;
5919 mRenderingFeature =
true;
5920 mCurrentParts.clear();
5925 mRenderingFeature =
false;
5927 const double prevOpacity = mMarker->opacity();
5928 mMarker->setOpacity( mMarker->opacity() * mFeatureSymbolOpacity );
5930 render( context, mCurrentParts, feature,
false );
5932 mFeatureSymbolOpacity = 1;
5933 mMarker->setOpacity( prevOpacity );
5941 mDensityAreaUnit = unit;
5944 mMarker->setOutputUnit( unit );
5952 return mMarker->outputUnit();
5961 return mMarker->usesMapUnits();
5970 mMarker->setMapUnitScale( scale );
5978 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...
static QgsSymbolLayer * createFromSld(QDomElement &element)
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
QgsSymbol * subSymbol() override
Returns the symbol's sub symbol, if present.
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
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 QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsCentroidFillSymbolLayer using the specified properties map containing symbol propert...
~QgsCentroidFillSymbolLayer() override
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
double mFeatureSymbolOpacity
QgsCentroidFillSymbolLayer()
QColor color() const override
Returns the "representative" color of the symbol layer.
bool clipOnCurrentPartOnly() const
Returns true if point markers should be clipped to the current part boundary only.
bool mClipOnCurrentPartOnly
Abstract base class for color ramps.
virtual QColor color(double value) const =0
Returns the color corresponding to a specified value.
virtual 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 QgsColorRamp * create(const QVariantMap &properties=QVariantMap())
Creates the symbol layer.
static QString typeString()
Returns the string identifier for QgsCptCityColorRamp.
double area() const override
Returns the planar, 2-dimensional area of the geometry.
Exports QGIS layers to the DXF format.
static double mapUnitScaleFactor(double scale, Qgis::RenderUnit symbolUnits, Qgis::DistanceUnit mapUnits, double mapUnitsPerPixel=1.0)
Returns scale factor for conversion to map units.
Qgis::DistanceUnit mapUnits() const
Retrieve map units.
double symbologyScale() const
Returns the reference scale for output.
RAII class to pop scope from an expression context on destruction.
Single scope for storing variables and functions for use within a QgsExpressionContext.
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
static const QString EXPR_GEOMETRY_POINT_NUM
Inbuilt variable name for point number variable.
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for the context.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
bool isValid() const
Returns the validity of this feature.
bool isCanceled() const
Tells whether the operation has been canceled already.
void _renderPolygon(QPainter *p, const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context)
Default method to render polygon.
double angle() const
Returns the rotation angle of the fill symbol, in degrees clockwise.
A geometry is the spatial representation of a feature.
QVector< QgsPointXY > randomPointsInPolygon(int count, const std::function< bool(const QgsPointXY &) > &acceptPoint, unsigned long seed=0, QgsFeedback *feedback=nullptr, int maxTriesPerPoint=0) const
Returns a list of count random points generated inside a (multi)polygon geometry (if acceptPoint is s...
static QgsGeometry fromRect(const QgsRectangle &rect)
Creates a new geometry from a QgsRectangle.
static QgsGeometry fromQPolygonF(const QPolygonF &polygon)
Construct geometry from a QPolygonF.
QgsAbstractGeometry * get()
Returns a modifiable (non-const) reference to the underlying abstract geometry primitive.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
bool 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.
QgsGeometry buffer(double distance, int segments) const
Returns a buffer region around this geometry having the given width and with a specified number of se...
static QgsGeometry unaryUnion(const QVector< QgsGeometry > &geometries, const QgsGeometryParameters ¶meters=QgsGeometryParameters())
Compute the unary union on a list of geometries.
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 QgsColorRamp * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsColorRamp from a map of properties.
static QString typeString()
Returns the string identifier for QgsGradientColorRamp.
void addStopsToGradient(QGradient *gradient, double opacity=1) const
Copy color ramp stops to a QGradient.
void setColorRamp(QgsColorRamp *ramp)
Sets the color ramp used for the gradient fill.
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
QColor color2() const
Returns the color for endpoint of gradient, only used if the gradient color type is set to SimpleTwoC...
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
bool canCauseArtifactsBetweenAdjacentTiles() const override
Returns true if the symbol layer rendering can cause visible artifacts across a single feature when t...
QgsGradientFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
QgsMapUnitScale mapUnitScale() const override
bool mReferencePoint1IsCentroid
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
Qgis::SymbolCoordinateReference coordinateMode() const
Returns the coordinate mode for gradient, which controls how the gradient stops are positioned.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
Qgis::SymbolCoordinateReference mCoordinateMode
QgsGradientFillSymbolLayer(const QColor &color=DEFAULT_SIMPLEFILL_COLOR, const QColor &color2=Qt::white, Qgis::GradientColorSource gradientColorType=Qgis::GradientColorSource::SimpleTwoColor, Qgis::GradientType gradientType=Qgis::GradientType::Linear, Qgis::SymbolCoordinateReference coordinateMode=Qgis::SymbolCoordinateReference::Feature, Qgis::GradientSpread gradientSpread=Qgis::GradientSpread::Pad)
Constructor for QgsGradientFillSymbolLayer.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsGradientFillSymbolLayer using the specified properties map containing symbol propert...
void setMapUnitScale(const QgsMapUnitScale &scale) override
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
Qgis::GradientSpread mGradientSpread
~QgsGradientFillSymbolLayer() override
Qgis::GradientType mGradientType
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
double dxfWidth(const QgsDxfExport &e, QgsSymbolRenderContext &context) const override
Gets line width.
QgsMapUnitScale mapUnitScale() const override
Qt::PenStyle dxfPenStyle() const override
Gets pen style.
Qgis::RenderUnit mStrokeWidthUnit
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
void setMapUnitScale(const QgsMapUnitScale &scale) override
virtual void applyDataDefinedSettings(QgsSymbolRenderContext &context)
Applies data defined settings prior to generating the fill symbol brush.
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
~QgsImageFillSymbolLayer() override
virtual bool applyBrushTransformFromContext(QgsSymbolRenderContext *context=nullptr) const
Returns true if the image brush should be transformed using the render context's texture origin.
static void multiplyOpacity(QImage &image, double factor, QgsFeedback *feedback=nullptr)
Multiplies opacity of image pixel values by a factor.
static void stackBlur(QImage &image, int radius, bool alphaOnly=false, QgsFeedback *feedback=nullptr)
Performs a stack blur on an image.
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.
QgsSymbol * subSymbol() override
Returns the symbol's sub symbol, if present.
bool hasDataDefinedProperties() const override
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
void setColor(const QColor &c) override
Sets the "representative" color for the symbol layer.
QImage toTiledPatternImage() const override
Renders the symbol layer as an image that can be used as a seamless pattern fill for polygons,...
double offset() const
Returns the offset distance for lines within the fill, which is the distance to offset the parallel l...
QgsLinePatternFillSymbolLayer()
double distance() const
Returns the distance between lines in the fill pattern.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QString ogrFeatureStyleWidth(double widthScaleFactor) const
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
~QgsLinePatternFillSymbolLayer() override
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
static QgsSymbolLayer * createFromSld(QDomElement &element)
Creates a new QgsLinePatternFillSymbolLayer from a SLD element.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsLinePatternFillSymbolLayer from a properties map.
Line string geometry type, with support for z-dimension and m-values.
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())
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.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsPointPatternFillSymbolLayer using the specified properties map containing symbol pro...
unsigned long seed() const
Returns the random number seed to use when randomly shifting points, or 0 if a truly random sequence ...
Qgis::RenderUnit mDisplacementYUnit
Qgis::MarkerClipMode clipMode() const
Returns the marker clipping mode, which defines how markers are clipped at the edges of shapes.
bool hasDataDefinedProperties() const override
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
double offsetY() const
Returns the vertical offset values for points in the pattern.
QgsSymbol * subSymbol() override
Returns the symbol's sub symbol, if present.
QgsMapUnitScale mDistanceXMapUnitScale
void setMapUnitScale(const QgsMapUnitScale &scale) override
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
QString layerType() const override
Returns a string that represents this layer type.
void applyDataDefinedSettings(QgsSymbolRenderContext &context) override
Applies data defined settings prior to generating the fill symbol brush.
Qgis::RenderUnit mRandomDeviationXUnit
Qgis::RenderUnit mOffsetXUnit
Qgis::RenderUnit mDistanceYUnit
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
QgsMapUnitScale mOffsetXMapUnitScale
void stopFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called after the layer has been rendered for a particular feature.
Qgis::RenderUnit mOffsetYUnit
QColor color() const override
Returns the "representative" color of the symbol layer.
Qgis::RenderUnit mRandomDeviationYUnit
QgsPointPatternFillSymbolLayer()
QgsMapUnitScale mRandomDeviationXMapUnitScale
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.
void setClipMode(Qgis::MarkerClipMode mode)
Sets the marker clipping mode, which defines how markers are clipped at the edges of shapes.
static QgsSymbolLayer * createFromSld(QDomElement &element)
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...
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsRandomMarkerFillSymbolLayer using the specified properties map containing symbol pro...
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
QString layerType() const override
Returns a string that represents this layer type.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
QgsRandomMarkerFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
void setMapUnitScale(const QgsMapUnitScale &scale) override
bool hasDataDefinedProperties() const override
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
void stopFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called after the layer has been rendered for a particular feature.
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
void setCountMethod(Qgis::PointCountMethod method)
Sets the count method used to randomly fill the polygon.
bool clipPoints() const
Returns true if point markers should be clipped to the polygon boundary.
bool canCauseArtifactsBetweenAdjacentTiles() const override
Returns true if the symbol layer rendering can cause visible artifacts across a single feature when t...
void setClipPoints(bool clipped)
Sets whether point markers should be clipped to the polygon boundary.
QgsSymbol * subSymbol() override
Returns the symbol's sub symbol, if present.
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
QColor color() const override
Returns the "representative" color of the symbol layer.
void setSeed(unsigned long seed)
Sets the random number seed to use when generating points, or 0 if a truly random sequence will be us...
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
void setPointCount(int count)
Sets the count of random points to render in the fill.
Qgis::PointCountMethod countMethod() const
Returns the count method used to randomly fill the polygon.
double densityArea() const
Returns the density area used to count the number of points to randomly fill the polygon.
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,...
static QgsSymbolLayer * createFromSld(QDomElement &element)
Creates a new QgsRasterFillSymbolLayer from a SLD element.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsRasterFillSymbolLayer from a properties map.
QString layerType() const override
Returns a string that represents this layer type.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QgsRasterFillSymbolLayer(const QString &imageFilePath=QString())
Constructor for QgsRasterFillSymbolLayer, using a raster fill from the specified imageFilePath.
double opacity() const
Returns the opacity for the raster image used in the fill.
~QgsRasterFillSymbolLayer() override
void setOpacity(double opacity)
Sets the opacity for the raster image used in the fill.
QColor color() const override
Returns the "representative" color of the symbol layer.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
QString imageFilePath() const
The path to the raster image used for the fill.
void setImageFilePath(const QString &imagePath)
Sets the path to the raster image used for the fill.
double height() const
Returns the height used for scaling the image used in the fill.
static void resolvePaths(QVariantMap &properties, const QgsPathResolver &pathResolver, bool saving)
Turns relative paths in properties map to absolute when reading and vice versa when writing.
QPointF offset() const
Returns the offset for the fill.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer's subsymbol. takes ownership of the passed symbol.
QgsRasterFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
bool applyBrushTransformFromContext(QgsSymbolRenderContext *context=nullptr) const override
Returns true if the image brush should be transformed using the render context's texture origin.
void setCoordinateMode(Qgis::SymbolCoordinateReference mode)
Set the coordinate mode for fill.
A rectangle specified with double values.
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.
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.
static QgsSymbolLayer * createFromSld(QDomElement &element)
Creates a new QgsSVGFillSymbolLayer from a SLD element.
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer's subsymbol. takes ownership of the passed symbol.
QColor svgStrokeColor() const
Returns the stroke color used for rendering the SVG content.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
Qgis::RenderUnit patternWidthUnit() const
Returns the units for the width of the SVG images in the pattern.
const QgsMapUnitScale & svgStrokeWidthMapUnitScale() const
Returns the map unit scale for the pattern's stroke.
double svgStrokeWidth() const
Returns the stroke width used for rendering the SVG content.
QString layerType() const override
Returns a string that represents this layer type.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QMap< QString, QgsProperty > parameters() const
Returns the dynamic SVG parameters.
QgsSVGFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
QgsSVGFillSymbolLayer(const QString &svgFilePath, double width=20, double rotation=0.0)
Constructor for QgsSVGFillSymbolLayer, using the SVG picture at the specified absolute file path.
void setSvgFilePath(const QString &svgPath)
Sets the path to the SVG file to render in the fill.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsSVGFillSymbolLayer from a properties map.
QColor svgFillColor() const
Returns the fill color used for rendering the SVG content.
static void resolvePaths(QVariantMap &properties, const QgsPathResolver &pathResolver, bool saving)
Turns relative paths in properties map to absolute when reading and vice versa when writing.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
const QgsMapUnitScale & patternWidthMapUnitScale() const
Returns the map unit scale for the pattern's width.
Qgis::RenderUnit svgStrokeWidthUnit() const
Returns the units for the stroke width.
double patternWidth() const
Returns the width of the rendered SVG content within the fill (i.e.
bool hasDataDefinedProperties() const override
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
~QgsSVGFillSymbolLayer() override
void setMapUnitScale(const QgsMapUnitScale &scale) override
Q_DECL_DEPRECATED void toSld(QDomDocument &doc, QDomElement &element, const QVariantMap &props) const override
Saves the symbol layer as SLD.
void applyDataDefinedSettings(QgsSymbolRenderContext &context) override
Applies data defined settings prior to generating the fill symbol brush.
QgsMapUnitScale mapUnitScale() const override
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
QgsSymbol * subSymbol() override
Returns the symbol's sub symbol, if present.
Scoped object for saving and restoring a QPainter object's state.
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
QgsShapeburstFillSymbolLayer(const QColor &color=DEFAULT_SIMPLEFILL_COLOR, const QColor &color2=Qt::white, Qgis::GradientColorSource colorType=Qgis::GradientColorSource::SimpleTwoColor, int blurRadius=0, bool useWholeShape=true, double maxDistance=5)
Constructor for QgsShapeburstFillSymbolLayer.
QgsShapeburstFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
~QgsShapeburstFillSymbolLayer() override
int blurRadius() const
Returns the blur radius, which controls the amount of blurring applied to the fill.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
QColor color2() const
Returns the color used for the endpoint of the shapeburst fill.
void setMapUnitScale(const QgsMapUnitScale &scale) override
QgsMapUnitScale mapUnitScale() const override
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
bool canCauseArtifactsBetweenAdjacentTiles() const override
Returns true if the symbol layer rendering can cause visible artifacts across a single feature when t...
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsShapeburstFillSymbolLayer using the specified properties map containing symbol prope...
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
QPointF offset() const
Returns the offset for the shapeburst fill.
bool useWholeShape() const
Returns whether the shapeburst fill is set to cover the entire shape.
bool ignoreRings() const
Returns whether the shapeburst fill is set to ignore polygon interior rings.
double maxDistance() const
Returns the maximum distance from the shape's boundary which is shaded.
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)
double dxfWidth(const QgsDxfExport &e, QgsSymbolRenderContext &context) const override
Gets line width.
Qt::PenJoinStyle penJoinStyle() const
QColor strokeColor() const override
Returns the stroke color for the symbol layer.
QColor dxfBrushColor(QgsSymbolRenderContext &context) const override
Gets brush/fill color.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
Qt::BrushStyle dxfBrushStyle() const override
Gets brush/fill style.
QString ogrFeatureStyle(double mmScaleFactor, double mapUnitScaleFactor) const override
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
Qgis::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
QImage toTiledPatternImage() const override
Renders the symbol layer as an image that can be used as a seamless pattern fill for polygons,...
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
QgsSimpleFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
Qt::PenStyle mStrokeStyle
QgsMapUnitScale mapUnitScale() const override
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
Qt::PenJoinStyle mPenJoinStyle
Qt::BrushStyle mBrushStyle
void setMapUnitScale(const QgsMapUnitScale &scale) override
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsSimpleFillSymbolLayer using the specified properties map containing symbol propertie...
static QgsSymbolLayer * createFromSld(QDomElement &element)
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)
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)
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.
void copyDataDefinedProperties(QgsSymbolLayer *destLayer) const
Copies all data defined properties of this layer to another symbol 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.
void copyPaintEffect(QgsSymbolLayer *destLayer) const
Copies paint effect of this layer to another 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.
Abstract base class for all rendered symbols.
QColor color() const
Returns the symbol's color.
Qgis::SymbolType type() const
Returns the symbol's type.
double interval() const
Returns the interval between individual symbols.
const QgsMapUnitScale & intervalMapUnitScale() const
Returns the map unit scale for the interval between symbols.
void setInterval(double interval)
Sets the interval between individual symbols.
Qgis::RenderUnit intervalUnit() const
Returns the units for the interval between symbols.
static Q_INVOKABLE Qgis::RenderUnit decodeRenderUnit(const QString &string, bool *ok=nullptr)
Decodes a render unit from a string.
static Q_INVOKABLE QString encodeUnit(Qgis::DistanceUnit unit)
Encodes a distance unit to a string.
static bool isNull(const QVariant &variant, 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.