46#include <QDomDocument>
49#include <QPagedPaintDevice>
52#include <QSvgRenderer>
55using namespace Qt::StringLiterals;
108void QgsSimpleFillSymbolLayer::applyDataDefinedSymbology(
QgsSymbolRenderContext &context, QBrush &brush, QPen &pen, QPen &selPen )
133 penColor.setAlphaF( context.
opacity() * penColor.alphaF() );
134 pen.setColor( penColor );
142 double width = exprVal.toDouble( &ok );
146 pen.setWidthF( width );
147 selPen.setWidthF( width );
184 if ( props.contains( u
"color"_s ) )
186 if ( props.contains( u
"style"_s ) )
188 if ( props.contains( u
"color_border"_s ) )
193 else if ( props.contains( u
"outline_color"_s ) )
197 else if ( props.contains( u
"line_color"_s ) )
202 if ( props.contains( u
"style_border"_s ) )
207 else if ( props.contains( u
"outline_style"_s ) )
211 else if ( props.contains( u
"line_style"_s ) )
215 if ( props.contains( u
"width_border"_s ) )
220 else if ( props.contains( u
"outline_width"_s ) )
222 strokeWidth = props[u
"outline_width"_s].toDouble();
224 else if ( props.contains( u
"line_width"_s ) )
228 if ( props.contains( u
"offset"_s ) )
230 if ( props.contains( u
"joinstyle"_s ) )
235 if ( props.contains( u
"border_width_unit"_s ) )
239 else if ( props.contains( u
"outline_width_unit"_s ) )
243 else if ( props.contains( u
"line_width_unit"_s ) )
247 if ( props.contains( u
"offset_unit"_s ) )
250 if ( props.contains( u
"border_width_map_unit_scale"_s ) )
252 if ( props.contains( u
"offset_map_unit_scale"_s ) )
255 sl->restoreOldDataDefinedProperties( props );
263 return u
"SimpleFill"_s;
280 selColor.setAlphaF( context.
opacity() );
339 if (
mBrush.style() == Qt::SolidPattern ||
mBrush.style() == Qt::NoBrush || !
dynamic_cast<QPagedPaintDevice *
>( p->device() ) )
351 p->setPen( Qt::NoPen );
355 p->setBrush( Qt::NoBrush );
372 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 );
447 const double alpha { props.value( u
"alpha"_s, QVariant() ).toDouble( &ok ) };
453 QDomElement fillElem = doc.createElement( u
"se:Fill"_s );
454 symbolizerElem.appendChild( fillElem );
461 QDomElement strokeElem = doc.createElement( u
"se:Stroke"_s );
462 symbolizerElem.appendChild( strokeElem );
466 const double alpha { props.value( u
"alpha"_s, QVariant() ).toDouble( &ok ) };
487 symbolStyle.append(
';' );
496 Qt::BrushStyle fillStyle;
500 QDomElement fillElem = element.firstChildElement( u
"Fill"_s );
503 QDomElement strokeElem = element.firstChildElement( u
"Stroke"_s );
509 double scaleFactor = 1.0;
510 const QString uom = element.attribute( u
"uom"_s );
517 sl->setOutputUnit( sldUnitSize );
526 return penBleed + offsetBleed;
584 QPixmap pixmap( QSize( 32, 32 ) );
585 pixmap.fill( Qt::transparent );
587 painter.begin( &pixmap );
588 painter.setRenderHint( QPainter::Antialiasing );
596 std::unique_ptr< QgsSimpleFillSymbolLayer > layerClone(
clone() );
597 layerClone->setStrokeStyle( Qt::PenStyle::NoPen );
598 layerClone->drawPreviewIcon( symbolContext, pixmap.size() );
600 return pixmap.toImage();
632 bool refPoint1IsCentroid =
false;
634 bool refPoint2IsCentroid =
false;
639 if ( props.contains( u
"type"_s ) )
641 if ( props.contains( u
"coordinate_mode"_s ) )
643 if ( props.contains( u
"spread"_s ) )
645 if ( props.contains( u
"color_type"_s ) )
647 if ( props.contains( u
"gradient_color"_s ) )
652 else if ( props.contains( u
"color"_s ) )
656 if ( props.contains( u
"gradient_color2"_s ) )
661 if ( props.contains( u
"reference_point1"_s ) )
663 if ( props.contains( u
"reference_point1_iscentroid"_s ) )
664 refPoint1IsCentroid = props[u
"reference_point1_iscentroid"_s].toInt();
665 if ( props.contains( u
"reference_point2"_s ) )
667 if ( props.contains( u
"reference_point2_iscentroid"_s ) )
668 refPoint2IsCentroid = props[u
"reference_point2_iscentroid"_s].toInt();
669 if ( props.contains( u
"angle"_s ) )
670 angle = props[u
"angle"_s].toDouble();
672 if ( props.contains( u
"offset"_s ) )
689 if ( props.contains( u
"offset_unit"_s ) )
691 if ( props.contains( u
"offset_map_unit_scale"_s ) )
694 sl->setReferencePoint1IsCentroid( refPoint1IsCentroid );
696 sl->setReferencePoint2IsCentroid( refPoint2IsCentroid );
697 sl->setAngle(
angle );
699 sl->setColorRamp( gradientRamp );
701 sl->restoreOldDataDefinedProperties( props );
718 return u
"GradientFill"_s;
721void QgsGradientFillSymbolLayer::applyDataDefinedSymbology(
QgsSymbolRenderContext &context,
const QPolygonF &points )
726 applyGradient( context,
mBrush,
mColor,
mColor2,
mGradientColorType,
mGradientRamp.get(),
mGradientType,
mCoordinateMode,
mGradientSpread,
mReferencePoint1,
mReferencePoint2,
mAngle );
765 if ( currentType == QObject::tr(
"linear" ) )
769 else if ( currentType == QObject::tr(
"radial" ) )
773 else if ( currentType == QObject::tr(
"conical" ) )
787 if ( currentCoordMode == QObject::tr(
"feature" ) )
791 else if ( currentCoordMode == QObject::tr(
"viewport" ) )
805 if ( currentSpread == QObject::tr(
"pad" ) )
809 else if ( currentSpread == QObject::tr(
"repeat" ) )
813 else if ( currentSpread == QObject::tr(
"reflect" ) )
860 if ( refPoint1IsCentroid || refPoint2IsCentroid )
865 QRectF bbox = points.boundingRect();
866 double centroidX = ( centroid.x() - bbox.left() ) / bbox.width();
867 double centroidY = ( centroid.y() - bbox.top() ) / bbox.height();
869 if ( refPoint1IsCentroid )
871 refPoint1X = centroidX;
872 refPoint1Y = centroidY;
874 if ( refPoint2IsCentroid )
876 refPoint2X = centroidX;
877 refPoint2Y = centroidY;
882 applyGradient( context,
mBrush,
color,
color2,
mGradientColorType,
mGradientRamp.get(),
gradientType,
coordinateMode, spread, QPointF( refPoint1X, refPoint1Y ), QPointF( refPoint2X, refPoint2Y ),
angle );
885QPointF QgsGradientFillSymbolLayer::rotateReferencePoint( QPointF refPoint,
double angle )
890 QLineF refLine = QLineF( QPointF( 0.5, 0.5 ), refPoint );
892 refLine.setAngle( refLine.angle() +
angle );
894 QPointF rotatedReferencePoint = refLine.p2();
896 if ( rotatedReferencePoint.x() > 1 )
897 rotatedReferencePoint.setX( 1 );
898 if ( rotatedReferencePoint.x() < 0 )
899 rotatedReferencePoint.setX( 0 );
900 if ( rotatedReferencePoint.y() > 1 )
901 rotatedReferencePoint.setY( 1 );
902 if ( rotatedReferencePoint.y() < 0 )
903 rotatedReferencePoint.setY( 0 );
905 return rotatedReferencePoint;
908void QgsGradientFillSymbolLayer::applyGradient(
912 const QColor &color2,
918 QPointF referencePoint1,
919 QPointF referencePoint2,
926 QColor fillColor2 =
color2;
927 fillColor2.setAlphaF( context.
opacity() * fillColor2.alphaF() );
938 gradient = QLinearGradient( rotatedReferencePoint1, rotatedReferencePoint2 );
941 gradient = QRadialGradient( rotatedReferencePoint1, QLineF( rotatedReferencePoint1, rotatedReferencePoint2 ).length() );
944 gradient = QConicalGradient( rotatedReferencePoint1, QLineF( rotatedReferencePoint1, rotatedReferencePoint2 ).
angle() );
950 gradient.setCoordinateMode( QGradient::ObjectBoundingMode );
953 gradient.setCoordinateMode( QGradient::StretchToDeviceMode );
959 gradient.setSpread( QGradient::PadSpread );
962 gradient.setSpread( QGradient::ReflectSpread );
965 gradient.setSpread( QGradient::RepeatSpread );
975 QgsGradientColorRamp *gradRamp =
static_cast<QgsGradientColorRamp *
>( gradientRamp );
982 gradient.setColorAt( 1.0, fillColor2 );
986 brush = QBrush( gradient );
993 selColor.setAlphaF( context.
opacity() );
1010 applyDataDefinedSymbology( context, points );
1014 p->setPen( Qt::NoPen );
1048 map[u
"type"_s] = QString::number(
static_cast<int>(
mGradientType ) );
1049 map[u
"coordinate_mode"_s] = QString::number(
static_cast< int >(
mCoordinateMode ) );
1050 map[u
"spread"_s] = QString::number(
static_cast< int >(
mGradientSpread ) );
1055 map[u
"angle"_s] = QString::number(
mAngle );
1080 return sl.release();
1144 if ( props.contains( u
"color_type"_s ) )
1148 if ( props.contains( u
"shapeburst_color"_s ) )
1153 else if ( props.contains( u
"color"_s ) )
1158 if ( props.contains( u
"shapeburst_color2"_s ) )
1163 else if ( props.contains( u
"gradient_color2"_s ) )
1167 if ( props.contains( u
"blur_radius"_s ) )
1169 blurRadius = props[u
"blur_radius"_s].toInt();
1171 if ( props.contains( u
"use_whole_shape"_s ) )
1175 if ( props.contains( u
"max_distance"_s ) )
1177 maxDistance = props[u
"max_distance"_s].toDouble();
1179 if ( props.contains( u
"offset"_s ) )
1198 if ( props.contains( u
"offset_unit"_s ) )
1202 if ( props.contains( u
"distance_unit"_s ) )
1206 if ( props.contains( u
"offset_map_unit_scale"_s ) )
1210 if ( props.contains( u
"distance_map_unit_scale"_s ) )
1214 if ( props.contains( u
"ignore_rings"_s ) )
1216 sl->setIgnoreRings( props[u
"ignore_rings"_s].toInt() );
1220 sl->setColorRamp( gradientRamp );
1223 sl->restoreOldDataDefinedProperties( props );
1225 return sl.release();
1230 return u
"ShapeburstFill"_s;
1240 if ( mGradientRamp.get() == ramp )
1243 mGradientRamp.reset( ramp );
1246void QgsShapeburstFillSymbolLayer::applyDataDefinedSymbology(
QgsSymbolRenderContext &context, QColor &color, QColor &color2,
int &blurRadius,
bool &useWholeShape,
double &maxDistance,
bool &ignoreRings )
1302 selColor.setAlphaF( context.
opacity() );
1303 mSelBrush = QBrush( selColor );
1320 if ( useSelectedColor )
1323 p->setBrush( mSelBrush );
1324 QPointF
offset = mOffset;
1359 int outputPixelMaxDist = 0;
1367 std::unique_ptr< QgsGradientColorRamp > twoColorGradientRamp;
1370 twoColorGradientRamp = std::make_unique< QgsGradientColorRamp >( color1,
color2 );
1374 p->setPen( QPen( Qt::NoPen ) );
1379 int pointsWidth =
static_cast< int >( std::round( points.boundingRect().width() ) );
1380 int pointsHeight =
static_cast< int >( std::round( points.boundingRect().height() ) );
1381 int imWidth = pointsWidth + ( sideBuffer * 2 );
1382 int imHeight = pointsHeight + ( sideBuffer * 2 );
1388 auto fillImage = std::make_unique< QImage >( imWidth, 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() );
1478 imgPainter.begin( fillImage.get() );
1479 imgPainter.setCompositionMode( QPainter::CompositionMode_DestinationIn );
1480 imgPainter.drawImage( 0, 0, *alphaImage );
1488 QPointF
offset = mOffset;
1505 p->drawImage( points.boundingRect().left() - sideBuffer, points.boundingRect().top() - sideBuffer, *fillImage );
1516void QgsShapeburstFillSymbolLayer::distanceTransform1d(
double *f,
int n,
int *v,
double *z,
double *d )
1522 for (
int q = 1; q <= n - 1; q++ )
1524 double s = ( ( f[q] +
static_cast< double >( q ) * q ) - ( f[v[k]] + (
static_cast< double >( v[k] ) * v[k] ) ) ) / ( 2 * q - 2 * v[k] );
1528 s = ( ( f[q] +
static_cast< double >( q ) * q ) - ( f[v[k]] + (
static_cast< double >( v[k] ) * v[k] ) ) ) / ( 2 * q - 2 * v[k] );
1537 for (
int q = 0; q <= n - 1; q++ )
1539 while ( z[k + 1] < q )
1541 d[q] =
static_cast< double >( q - v[k] ) * ( q - v[k] ) + f[v[k]];
1546void QgsShapeburstFillSymbolLayer::distanceTransform2d(
double *im,
int width,
int height,
QgsRenderContext &context )
1548 int maxDimension = std::max( width, height );
1549 double *f =
new double[maxDimension];
1550 int *v =
new int[maxDimension];
1551 double *z =
new double[maxDimension + 1];
1552 double *d =
new double[maxDimension];
1555 for (
int x = 0; x < width; x++ )
1560 for (
int y = 0; y < height; y++ )
1562 f[y] = im[x +
static_cast< std::size_t
>( y ) * width];
1564 distanceTransform1d( f, height, v, z, d );
1565 for (
int y = 0; y < height; y++ )
1567 im[x +
static_cast< std::size_t
>( y ) * width] = d[y];
1572 for (
int y = 0; y < height; y++ )
1577 for (
int x = 0; x < width; x++ )
1579 f[x] = im[x +
static_cast< std::size_t
>( y ) * width];
1581 distanceTransform1d( f, width, v, z, d );
1582 for (
int x = 0; x < width; x++ )
1584 im[x +
static_cast< std::size_t
>( y ) * width] = d[x];
1595double *QgsShapeburstFillSymbolLayer::distanceTransform( QImage *im,
QgsRenderContext &context )
1597 int width = im->width();
1598 int height = im->height();
1600 double *dtArray =
new double[
static_cast< std::size_t
>( width ) * height];
1604 std::size_t idx = 0;
1605 for (
int heightIndex = 0; heightIndex < height; ++heightIndex )
1610 const QRgb *scanLine =
reinterpret_cast< const QRgb *
>( im->constScanLine( heightIndex ) );
1611 for (
int widthIndex = 0; widthIndex < width; ++widthIndex )
1613 tmpRgb = scanLine[widthIndex];
1614 if ( qRed( tmpRgb ) == 0 )
1629 distanceTransform2d( dtArray, width, height, context );
1634void QgsShapeburstFillSymbolLayer::dtArrayToQImage(
double *array, QImage *im,
QgsColorRamp *ramp,
QgsRenderContext &context,
bool useWholeShape,
int maxPixelDistance )
1636 int width = im->width();
1637 int height = im->height();
1640 double maxDistanceValue;
1645 double dtMaxValue = array[0];
1646 for ( std::size_t i = 1; i < static_cast< std::size_t >( width ) * height; ++i )
1648 if ( array[i] > dtMaxValue )
1650 dtMaxValue = array[i];
1655 maxDistanceValue = std::sqrt( dtMaxValue );
1660 maxDistanceValue = maxPixelDistance;
1664 std::size_t idx = 0;
1665 double squaredVal = 0;
1668 for (
int heightIndex = 0; heightIndex < height; ++heightIndex )
1673 QRgb *scanLine =
reinterpret_cast< QRgb *
>( im->scanLine( heightIndex ) );
1674 for (
int widthIndex = 0; widthIndex < width; ++widthIndex )
1677 squaredVal = array[idx];
1680 if ( maxDistanceValue > 0 )
1682 pixVal = squaredVal > 0 ? std::min( ( std::sqrt( squaredVal ) / maxDistanceValue ), 1.0 ) : 0;
1691 scanLine[widthIndex] = qPremultiply( ramp->
color( pixVal ).rgba() );
1702 map[u
"color_type"_s] = QString::number(
static_cast< int >( mColorType ) );
1703 map[u
"blur_radius"_s] = QString::number( mBlurRadius );
1704 map[u
"use_whole_shape"_s] = QString::number( mUseWholeShape );
1705 map[u
"max_distance"_s] = QString::number( mMaxDistance );
1708 map[u
"ignore_rings"_s] = QString::number( mIgnoreRings );
1712 if ( mGradientRamp )
1714 map.insert( mGradientRamp->properties() );
1722 auto sl = std::make_unique< QgsShapeburstFillSymbolLayer >(
mColor, mColor2, mColorType, mBlurRadius, mUseWholeShape, mMaxDistance );
1723 if ( mGradientRamp )
1725 sl->setColorRamp( mGradientRamp->clone() );
1727 sl->setDistanceUnit( mDistanceUnit );
1728 sl->setDistanceMapUnitScale( mDistanceMapUnitScale );
1729 sl->setIgnoreRings( mIgnoreRings );
1730 sl->setOffset( mOffset );
1731 sl->setOffsetUnit( mOffsetUnit );
1732 sl->setOffsetMapUnitScale( mOffsetMapUnitScale );
1734 return sl.release();
1739 double offsetBleed = context.
convertToPainterUnits( std::max( std::fabs( mOffset.x() ), std::fabs( mOffset.y() ) ), mOffsetUnit, mOffsetMapUnitScale );
1750 mDistanceUnit = unit;
1756 if ( mDistanceUnit == mOffsetUnit )
1758 return mDistanceUnit;
1773 mDistanceMapUnitScale = scale;
1774 mOffsetMapUnitScale = scale;
1779 if ( mDistanceMapUnitScale == mOffsetMapUnitScale )
1781 return mDistanceMapUnitScale;
1805 p->setPen( QPen( Qt::NoPen ) );
1807 QTransform bkTransform =
mBrush.transform();
1811 QTransform t =
mBrush.transform();
1812 t.translate( leftCorner.x(), leftCorner.y() );
1813 mBrush.setTransform( t );
1817 QTransform t =
mBrush.transform();
1818 t.translate( 0, 0 );
1819 mBrush.setTransform( t );
1823 if ( useSelectedColor )
1826 p->setBrush( QBrush( selColor ) );
1832 QTransform t =
mBrush.transform();
1834 mBrush.setTransform( t );
1839 mBrush.setTransform( bkTransform );
1875 return Qt::SolidLine;
1879 return Qt::SolidLine;
1883 return mStroke->dxfPenStyle();
1919 , mPatternWidth( width )
1923 mColor = QColor( 255, 255, 255 );
1929 , mPatternWidth( width )
1930 , mSvgData( svgData )
1935 mColor = QColor( 255, 255, 255 );
1936 setDefaultSvgParams();
1944 mPatternWidthUnit = unit;
1945 mSvgStrokeWidthUnit = unit;
1948 mStroke->setOutputUnit( unit );
1954 if ( mPatternWidthUnit != unit || mSvgStrokeWidthUnit != unit ||
mStrokeWidthUnit != unit )
1964 mPatternWidthMapUnitScale = scale;
1965 mSvgStrokeWidthMapUnitScale = scale;
1972 return mPatternWidthMapUnitScale;
1982 mSvgFilePath = svgPath;
1983 setDefaultSvgParams();
2006 std::unique_ptr< QgsSVGFillSymbolLayer > symbolLayer;
2009 symbolLayer = std::make_unique< QgsSVGFillSymbolLayer >(
svgFilePath, width,
angle );
2015 data = QByteArray::fromHex(
properties[u
"data"_s].toString().toLocal8Bit() );
2017 symbolLayer = std::make_unique< QgsSVGFillSymbolLayer >( data, width,
angle );
2021 if (
properties.contains( u
"svgFillColor"_s ) )
2026 else if (
properties.contains( u
"color"_s ) )
2030 if (
properties.contains( u
"svgOutlineColor"_s ) )
2035 else if (
properties.contains( u
"outline_color"_s ) )
2039 else if (
properties.contains( u
"line_color"_s ) )
2043 if (
properties.contains( u
"svgOutlineWidth"_s ) )
2046 symbolLayer->setSvgStrokeWidth(
properties[u
"svgOutlineWidth"_s].toDouble() );
2048 else if (
properties.contains( u
"outline_width"_s ) )
2050 symbolLayer->setSvgStrokeWidth(
properties[u
"outline_width"_s].toDouble() );
2052 else if (
properties.contains( u
"line_width"_s ) )
2054 symbolLayer->setSvgStrokeWidth(
properties[u
"line_width"_s].toDouble() );
2058 if (
properties.contains( u
"pattern_width_unit"_s ) )
2062 if (
properties.contains( u
"pattern_width_map_unit_scale"_s ) )
2066 if (
properties.contains( u
"svg_outline_width_unit"_s ) )
2070 if (
properties.contains( u
"svg_outline_width_map_unit_scale"_s ) )
2074 if (
properties.contains( u
"outline_width_unit"_s ) )
2078 if (
properties.contains( u
"outline_width_map_unit_scale"_s ) )
2083 if (
properties.contains( u
"parameters"_s ) )
2089 symbolLayer->restoreOldDataDefinedProperties(
properties );
2091 return symbolLayer.release();
2096 QVariantMap::iterator it =
properties.find( u
"svgFile"_s );
2108 return u
"SVGFill"_s;
2111void QgsSVGFillSymbolLayer::applyPattern(
2113 const QString &svgFilePath,
2114 double patternWidth,
2116 const QColor &svgFillColor,
2117 const QColor &svgStrokeColor,
2118 double svgStrokeWidth,
2126 if ( mSvgViewBox.isNull() )
2133 if (
static_cast< int >( size ) < 1.0 || 10000.0 < size )
2135 brush.setTextureImage( QImage() );
2139 bool fitsInCache =
true;
2146 QPicture patternPict
2149 double hwRatio = 1.0;
2150 if ( patternPict.width() > 0 )
2152 hwRatio =
static_cast< double >( patternPict.height() ) /
static_cast< double >( patternPict.width() );
2154 patternImage = QImage(
static_cast< int >( size ),
static_cast< int >( size * hwRatio ), QImage::Format_ARGB32_Premultiplied );
2155 patternImage.fill( 0 );
2157 QPainter p( &patternImage );
2158 p.drawPicture( QPointF( size / 2, size * hwRatio / 2 ), patternPict );
2161 QTransform brushTransform;
2164 QImage transparentImage = patternImage.copy();
2166 brush.setTextureImage( transparentImage );
2170 brush.setTextureImage( patternImage );
2172 brush.setTransform( brushTransform );
2180 applyPattern(
mBrush, mSvgFilePath, mPatternWidth, mPatternWidthUnit,
mColor, mSvgStrokeColor, mSvgStrokeWidth, mSvgStrokeWidthUnit, context, mPatternWidthMapUnitScale, mSvgStrokeWidthMapUnitScale, evaluatedParameters );
2204 mStroke->renderPolyline( points, context.
feature(), context.
renderContext(), -1, useSelectedColor );
2207 for (
auto ringIt = rings->constBegin(); ringIt != rings->constEnd(); ++ringIt )
2209 mStroke->renderPolyline( *ringIt, context.
feature(), context.
renderContext(), -1, useSelectedColor );
2218 if ( !mSvgFilePath.isEmpty() )
2220 map.insert( u
"svgFile"_s, mSvgFilePath );
2224 map.insert( u
"data"_s, QString( mSvgData.toHex() ) );
2227 map.insert( u
"width"_s, QString::number( mPatternWidth ) );
2228 map.insert( u
"angle"_s, QString::number(
mAngle ) );
2233 map.insert( u
"outline_width"_s, QString::number( mSvgStrokeWidth ) );
2250 std::unique_ptr< QgsSVGFillSymbolLayer > clonedLayer;
2251 if ( !mSvgFilePath.isEmpty() )
2253 clonedLayer = std::make_unique< QgsSVGFillSymbolLayer >( mSvgFilePath, mPatternWidth,
mAngle );
2254 clonedLayer->setSvgFillColor(
mColor );
2255 clonedLayer->setSvgStrokeColor( mSvgStrokeColor );
2256 clonedLayer->setSvgStrokeWidth( mSvgStrokeWidth );
2260 clonedLayer = std::make_unique< QgsSVGFillSymbolLayer >( mSvgData, mPatternWidth,
mAngle );
2263 clonedLayer->setPatternWidthUnit( mPatternWidthUnit );
2264 clonedLayer->setPatternWidthMapUnitScale( mPatternWidthMapUnitScale );
2265 clonedLayer->setSvgStrokeWidthUnit( mSvgStrokeWidthUnit );
2266 clonedLayer->setSvgStrokeWidthMapUnitScale( mSvgStrokeWidthMapUnitScale );
2270 clonedLayer->setParameters( mParameters );
2274 clonedLayer->setSubSymbol( mStroke->clone() );
2277 return clonedLayer.release();
2284 toSld( doc, element, context );
2290 QDomElement symbolizerElem = doc.createElement( u
"se:PolygonSymbolizer"_s );
2291 if ( !props.value( u
"uom"_s, QString() ).toString().isEmpty() )
2292 symbolizerElem.setAttribute( u
"uom"_s, props.value( u
"uom"_s, QString() ).toString() );
2293 element.appendChild( symbolizerElem );
2297 QDomElement fillElem = doc.createElement( u
"se:Fill"_s );
2298 symbolizerElem.appendChild( fillElem );
2300 QDomElement graphicFillElem = doc.createElement( u
"se:GraphicFill"_s );
2301 fillElem.appendChild( graphicFillElem );
2303 QDomElement graphicElem = doc.createElement( u
"se:Graphic"_s );
2304 graphicFillElem.appendChild( graphicElem );
2306 if ( !mSvgFilePath.isEmpty() )
2318 context.
pushWarning( QObject::tr(
"Exporting embedded SVG content to SLD is not supported" ) );
2324 double angle = props.value( u
"angle"_s, u
"0"_s ).toDouble( &ok );
2327 angleFunc = u
"%1 + %2"_s.arg( props.value( u
"angle"_s, u
"0"_s ).toString() ).arg(
mAngle );
2340 mStroke->toSld( doc, element, context );
2355 return mStroke.get();
2362 mStroke.reset(
nullptr );
2375 mStroke.reset( lineSymbol );
2385 if ( mStroke && mStroke->symbolLayer( 0 ) )
2387 double subLayerBleed = mStroke->symbolLayer( 0 )->estimateMaxBleed( context );
2388 return subLayerBleed;
2398 return QColor( Qt::black );
2400 return mStroke->
color();
2407 attr.unite( mStroke->usedAttributes( context ) );
2415 if ( mStroke && mStroke->hasDataDefinedProperties() )
2422 QString path, mimeType;
2424 Qt::PenStyle penStyle;
2425 double size, strokeWidth;
2427 QDomElement fillElem = element.firstChildElement( u
"Fill"_s );
2428 if ( fillElem.isNull() )
2431 QDomElement graphicFillElem = fillElem.firstChildElement( u
"GraphicFill"_s );
2432 if ( graphicFillElem.isNull() )
2435 QDomElement graphicElem = graphicFillElem.firstChildElement( u
"Graphic"_s );
2436 if ( graphicElem.isNull() )
2442 if ( mimeType !=
"image/svg+xml"_L1 )
2447 double scaleFactor = 1.0;
2448 const QString uom = element.attribute( u
"uom"_s );
2450 size = size * scaleFactor;
2451 strokeWidth = strokeWidth * scaleFactor;
2458 double d = angleFunc.toDouble( &ok );
2463 auto sl = std::make_unique< QgsSVGFillSymbolLayer >( path, size,
angle );
2464 sl->setOutputUnit( sldUnitSize );
2467 sl->setSvgStrokeWidth( strokeWidth );
2470 QDomElement strokeElem = element.firstChildElement( u
"Stroke"_s );
2471 if ( !strokeElem.isNull() )
2477 layers.append( l.release() );
2482 return sl.release();
2503 double width = mPatternWidth;
2509 QString svgFile = mSvgFilePath;
2528 double strokeWidth = mSvgStrokeWidth;
2536 applyPattern(
mBrush, svgFile, width, mPatternWidthUnit,
svgFillColor,
svgStrokeColor, strokeWidth, mSvgStrokeWidthUnit, context, mPatternWidthMapUnitScale, mSvgStrokeWidthMapUnitScale, evaluatedParameters );
2539void QgsSVGFillSymbolLayer::storeViewBox()
2541 if ( !mSvgData.isEmpty() )
2543 QSvgRenderer r( mSvgData );
2546 mSvgViewBox = r.viewBoxF();
2551 mSvgViewBox = QRectF();
2554void QgsSVGFillSymbolLayer::setDefaultSvgParams()
2556 if ( mSvgFilePath.isEmpty() )
2561 bool hasFillParam, hasFillOpacityParam, hasStrokeParam, hasStrokeWidthParam, hasStrokeOpacityParam;
2562 bool hasDefaultFillColor, hasDefaultFillOpacity, hasDefaultStrokeColor, hasDefaultStrokeWidth, hasDefaultStrokeOpacity;
2563 QColor defaultFillColor, defaultStrokeColor;
2564 double defaultStrokeWidth, defaultFillOpacity, defaultStrokeOpacity;
2568 hasDefaultFillColor,
2570 hasFillOpacityParam,
2571 hasDefaultFillOpacity,
2574 hasDefaultStrokeColor,
2576 hasStrokeWidthParam,
2577 hasDefaultStrokeWidth,
2579 hasStrokeOpacityParam,
2580 hasDefaultStrokeOpacity,
2581 defaultStrokeOpacity
2584 double newFillOpacity = hasFillOpacityParam ?
mColor.alphaF() : 1.0;
2585 double newStrokeOpacity = hasStrokeOpacityParam ? mSvgStrokeColor.alphaF() : 1.0;
2587 if ( hasDefaultFillColor )
2589 mColor = defaultFillColor;
2590 mColor.setAlphaF( newFillOpacity );
2592 if ( hasDefaultFillOpacity )
2594 mColor.setAlphaF( defaultFillOpacity );
2596 if ( hasDefaultStrokeColor )
2598 mSvgStrokeColor = defaultStrokeColor;
2599 mSvgStrokeColor.setAlphaF( newStrokeOpacity );
2601 if ( hasDefaultStrokeOpacity )
2603 mSvgStrokeColor.setAlphaF( defaultStrokeOpacity );
2605 if ( hasDefaultStrokeWidth )
2607 mSvgStrokeWidth = defaultStrokeWidth;
2620 mFillLineSymbol = std::make_unique<QgsLineSymbol>();
2628 mFillLineSymbol->setWidth( w );
2634 mFillLineSymbol->setColor(
c );
2640 return mFillLineSymbol ? mFillLineSymbol->color() :
mColor;
2652 mFillLineSymbol.reset( qgis::down_cast<QgsLineSymbol *>( symbol ) );
2661 return mFillLineSymbol.get();
2667 if ( mFillLineSymbol )
2668 attr.unite( mFillLineSymbol->usedAttributes( context ) );
2676 if ( mFillLineSymbol && mFillLineSymbol->hasDataDefinedProperties() )
2697 double lineAngleRad { qDegreesToRadians( mLineAngle ) };
2699 const int quadrant {
static_cast<int>( lineAngleRad / M_PI_2 ) };
2700 Q_ASSERT( quadrant >= 0 && quadrant <= 3 );
2710 lineAngleRad -= M_PI / 2;
2715 lineAngleRad -= M_PI;
2720 lineAngleRad -= M_PI + M_PI_2;
2728 QSize size {
static_cast<int>( distancePx ),
static_cast<int>( distancePx ) };
2730 if (
static_cast<int>( mLineAngle ) % 90 != 0 )
2732 size = QSize(
static_cast<int>( distancePx / std::sin( lineAngleRad ) ),
static_cast<int>( distancePx / std::cos( lineAngleRad ) ) );
2735 QPixmap pixmap( size );
2736 pixmap.fill( Qt::transparent );
2738 painter.begin( &pixmap );
2739 painter.setRenderHint( QPainter::Antialiasing );
2747 std::unique_ptr< QgsLinePatternFillSymbolLayer > layerClone(
clone() );
2748 layerClone->setOffset( 0 );
2749 layerClone->drawPreviewIcon( symbolContext, pixmap.size() );
2751 return pixmap.toImage();
2762 mDistanceUnit = unit;
2763 mLineWidthUnit = unit;
2766 if ( mFillLineSymbol )
2767 mFillLineSymbol->setOutputUnit( unit );
2793 mDistanceMapUnitScale = scale;
2794 mLineWidthMapUnitScale = scale;
2795 mOffsetMapUnitScale = scale;
2802 return mDistanceMapUnitScale;
2809 auto patternLayer = std::make_unique< QgsLinePatternFillSymbolLayer >();
2815 QColor
color( Qt::black );
2823 else if (
properties.contains( u
"angle"_s ) )
2827 patternLayer->setLineAngle(
lineAngle );
2833 patternLayer->setDistance(
distance );
2840 else if (
properties.contains( u
"outline_width"_s ) )
2844 else if (
properties.contains( u
"line_width"_s ) )
2848 patternLayer->setLineWidth(
lineWidth );
2854 else if (
properties.contains( u
"outline_color"_s ) )
2858 else if (
properties.contains( u
"line_color"_s ) )
2862 patternLayer->setColor(
color );
2868 patternLayer->setOffset(
offset );
2871 if (
properties.contains( u
"distance_unit"_s ) )
2875 if (
properties.contains( u
"distance_map_unit_scale"_s ) )
2879 if (
properties.contains( u
"line_width_unit"_s ) )
2883 else if (
properties.contains( u
"outline_width_unit"_s ) )
2887 if (
properties.contains( u
"line_width_map_unit_scale"_s ) )
2891 if (
properties.contains( u
"offset_unit"_s ) )
2895 if (
properties.contains( u
"offset_map_unit_scale"_s ) )
2899 if (
properties.contains( u
"outline_width_unit"_s ) )
2903 if (
properties.contains( u
"outline_width_map_unit_scale"_s ) )
2907 if (
properties.contains( u
"coordinate_reference"_s ) )
2916 patternLayer->restoreOldDataDefinedProperties(
properties );
2918 return patternLayer.release();
2923 return u
"LinePatternFill"_s;
2926bool QgsLinePatternFillSymbolLayer::applyPattern(
const QgsSymbolRenderContext &context, QBrush &brush,
double lineAngle,
double distance )
2928 mBrush.setTextureImage( QImage() );
2930 if ( !mFillLineSymbol )
2935 std::unique_ptr< QgsLineSymbol > fillLineSymbol( mFillLineSymbol->clone() );
2936 if ( !fillLineSymbol )
2951 outputPixelOffset = std::fmod( outputPixelOffset, outputPixelDist );
2952 if ( outputPixelOffset > outputPixelDist / 2.0 )
2953 outputPixelOffset -= outputPixelDist;
2957 double outputPixelBleed = 0;
2958 double outputPixelInterval = 0;
2959 for (
int i = 0; i < fillLineSymbol->symbolLayerCount(); i++ )
2963 outputPixelBleed = std::max( outputPixelBleed, outputPixelLayerBleed );
2965 QgsMarkerLineSymbolLayer *markerLineLayer =
dynamic_cast<QgsMarkerLineSymbolLayer *
>( layer );
2966 if ( markerLineLayer )
2975 outputPixelInterval = std::max( outputPixelInterval, outputPixelLayerInterval );
2979 if ( outputPixelInterval > 0 )
2983 double intervalScale = std::round( outputPixelInterval ) / outputPixelInterval;
2984 outputPixelInterval = std::round( outputPixelInterval );
2986 for (
int i = 0; i < fillLineSymbol->symbolLayerCount(); i++ )
2990 QgsMarkerLineSymbolLayer *markerLineLayer =
dynamic_cast<QgsMarkerLineSymbolLayer *
>( layer );
2991 if ( markerLineLayer )
3005 height = outputPixelDist;
3006 width = outputPixelInterval > 0 ? outputPixelInterval : height;
3010 width = outputPixelDist;
3011 height = outputPixelInterval > 0 ? outputPixelInterval : width;
3015 height = outputPixelDist / std::cos(
lineAngle * M_PI / 180 );
3016 width = outputPixelDist / std::sin(
lineAngle * M_PI / 180 );
3019 lineAngle = 180 * std::atan2(
static_cast< double >( height ),
static_cast< double >( width ) ) / M_PI;
3025 height = std::abs( height );
3026 width = std::abs( width );
3028 outputPixelDist = std::abs( height * std::cos(
lineAngle * M_PI / 180 ) );
3032 int offsetHeight =
static_cast< int >( std::round( outputPixelOffset / std::cos(
lineAngle * M_PI / 180 ) ) );
3033 outputPixelOffset = offsetHeight * std::cos(
lineAngle * M_PI / 180 );
3042 int bufferMulti =
static_cast< int >( std::max( std::ceil( outputPixelBleed / width ), std::ceil( outputPixelBleed / width ) ) );
3046 bufferMulti = std::max( bufferMulti, 1 );
3048 int xBuffer = width * bufferMulti;
3049 int yBuffer = height * bufferMulti;
3050 int innerWidth = width;
3051 int innerHeight = height;
3052 width += 2 * xBuffer;
3053 height += 2 * yBuffer;
3056 if ( width > 2000 || height > 2000 || width == 0 || height == 0 )
3061 QImage patternImage( width, height, QImage::Format_ARGB32 );
3062 patternImage.fill( 0 );
3064 QPointF p1, p2, p3, p4, p5, p6;
3067 p1 = QPointF( 0, yBuffer );
3068 p2 = QPointF( width, yBuffer );
3069 p3 = QPointF( 0, yBuffer + innerHeight );
3070 p4 = QPointF( width, yBuffer + innerHeight );
3074 p1 = QPointF( xBuffer, height );
3075 p2 = QPointF( xBuffer, 0 );
3076 p3 = QPointF( xBuffer + innerWidth, height );
3077 p4 = QPointF( xBuffer + innerWidth, 0 );
3081 dx = outputPixelDist * std::cos( ( 90 -
lineAngle ) * M_PI / 180.0 );
3082 dy = outputPixelDist * std::sin( ( 90 -
lineAngle ) * M_PI / 180.0 );
3083 p1 = QPointF( 0, height );
3084 p2 = QPointF( width, 0 );
3085 p3 = QPointF( -dx, height - dy );
3086 p4 = QPointF( width - dx, -dy );
3087 p5 = QPointF( dx, height + dy );
3088 p6 = QPointF( width + dx, dy );
3092 dx = outputPixelDist * std::cos( ( 90 -
lineAngle ) * M_PI / 180.0 );
3093 dy = outputPixelDist * std::sin( ( 90 -
lineAngle ) * M_PI / 180.0 );
3094 p1 = QPointF( width, 0 );
3095 p2 = QPointF( 0, height );
3096 p3 = QPointF( width - dx, -dy );
3097 p4 = QPointF( -dx, height - dy );
3098 p5 = QPointF( width + dx, dy );
3099 p6 = QPointF( dx, height + dy );
3103 dy = outputPixelDist * std::cos( ( 180 -
lineAngle ) * M_PI / 180 );
3104 dx = outputPixelDist * std::sin( ( 180 -
lineAngle ) * M_PI / 180 );
3105 p1 = QPointF( 0, 0 );
3106 p2 = QPointF( width, height );
3107 p5 = QPointF( dx, -dy );
3108 p6 = QPointF( width + dx, height - dy );
3109 p3 = QPointF( -dx, dy );
3110 p4 = QPointF( width - dx, height + dy );
3114 dy = outputPixelDist * std::cos( ( 180 -
lineAngle ) * M_PI / 180 );
3115 dx = outputPixelDist * std::sin( ( 180 -
lineAngle ) * M_PI / 180 );
3116 p1 = QPointF( width, height );
3117 p2 = QPointF( 0, 0 );
3118 p5 = QPointF( width + dx, height - dy );
3119 p6 = QPointF( dx, -dy );
3120 p3 = QPointF( width - dx, height + dy );
3121 p4 = QPointF( -dx, dy );
3128 p3 = QPointF( tempPt.x(), tempPt.y() );
3130 p4 = QPointF( tempPt.x(), tempPt.y() );
3132 p5 = QPointF( tempPt.x(), tempPt.y() );
3134 p6 = QPointF( tempPt.x(), tempPt.y() );
3138 p1 = QPointF( tempPt.x(), tempPt.y() );
3140 p2 = QPointF( tempPt.x(), tempPt.y() );
3143 QPainter p( &patternImage );
3147 p.setRenderHint( QPainter::Antialiasing,
false );
3148 QPen pen( QColor( Qt::black ) );
3149 pen.setWidthF( 0.1 );
3150 pen.setCapStyle( Qt::FlatCap );
3155 QPolygon polygon = QPolygon() << QPoint( 0, 0 ) << QPoint( width - 1, 0 ) << QPoint( width - 1, height - 1 ) << QPoint( 0, height - 1 ) << QPoint( 0, 0 );
3156 p.drawPolygon( polygon );
3158 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 );
3159 p.drawPolygon( polygon );
3165 p.setRenderHint( QPainter::Antialiasing,
true );
3168 QgsRenderContext lineRenderContext;
3178 fillLineSymbol->startRender( lineRenderContext, context.
fields() );
3180 QVector<QPolygonF> polygons;
3181 polygons.append( QPolygonF() << p1 << p2 );
3182 polygons.append( QPolygonF() << p3 << p4 );
3185 polygons.append( QPolygonF() << p5 << p6 );
3189 for (
const QPolygonF &polygon : std::as_const( polygons ) )
3191 fillLineSymbol->renderPolyline( polygon, context.
feature(), lineRenderContext, -1, useSelectedColor );
3194 fillLineSymbol->stopRender( lineRenderContext );
3198 patternImage = patternImage.copy( xBuffer, yBuffer, patternImage.width() - 2 * xBuffer, patternImage.height() - 2 * yBuffer );
3203 QImage transparentImage = patternImage.copy();
3205 brush.setTextureImage( transparentImage );
3209 brush.setTextureImage( patternImage );
3212 QTransform brushTransform;
3213 brush.setTransform( brushTransform );
3223 || ( mFillLineSymbol && mFillLineSymbol->hasDataDefinedProperties() )
3227 if ( !mRenderUsingLines )
3231 mRenderUsingLines = !applyPattern( context,
mBrush, mLineAngle, mDistance );
3234 if ( mRenderUsingLines && mFillLineSymbol )
3238 mFillLineSymbolRenderStarted =
true;
3244 if ( mFillLineSymbolRenderStarted )
3247 mFillLineSymbolRenderStarted =
false;
3254 if ( !useSelectedColor && !mRenderUsingLines )
3261 if ( !mFillLineSymbol )
3264 if ( !mFillLineSymbolRenderStarted )
3268 mFillLineSymbolRenderStarted =
true;
3298 outputPixelOffset = std::fmod( outputPixelOffset, outputPixelDistance );
3299 if ( outputPixelOffset > outputPixelDistance / 2.0 )
3300 outputPixelOffset -= outputPixelDistance;
3302 p->setPen( QPen( Qt::NoPen ) );
3327 std::unique_ptr< QgsPolygon > shapePolygon;
3328 std::unique_ptr< QgsGeometryEngine > shapeEngine;
3336 shapePolygon = std::make_unique< QgsPolygon >();
3338 shapePolygon->setExteriorRing( fromPolygon.release() );
3341 for (
const QPolygonF &ring : *rings )
3344 shapePolygon->addInteriorRing( fromRing.release() );
3348 shapeEngine->prepareGeometry();
3355 path.addPolygon( points );
3358 for (
const QPolygonF &ring : *rings )
3360 path.addPolygon( ring );
3363 p->setClipPath( path, Qt::IntersectClip );
3369 const QRectF boundingRect = points.boundingRect();
3371 QTransform invertedRotateTransform;
3377 QTransform transform;
3378 if ( applyBrushTransform )
3381 transform.translate( -boundingRect.center().x(), -boundingRect.center().y() );
3383 transform.translate( boundingRect.center().x(), boundingRect.center().y() );
3391 const QRectF transformedBounds = transform.map( points ).boundingRect();
3395 left = transformedBounds.left() - buffer * 2;
3396 top = transformedBounds.top() - buffer * 2;
3397 right = transformedBounds.right() + buffer * 2;
3398 bottom = transformedBounds.bottom() + buffer * 2;
3399 invertedRotateTransform = transform.inverted();
3401 if ( !applyBrushTransform )
3403 top -= transformedBounds.top() - ( outputPixelDistance * std::floor( transformedBounds.top() / outputPixelDistance ) );
3408 const bool needsExpressionContext = mFillLineSymbol->hasDataDefinedProperties();
3413 int currentLine = 0;
3414 for (
double currentY = top; currentY <= bottom; currentY += outputPixelDistance )
3419 if ( needsExpressionContext )
3423 double y1 = currentY;
3425 double y2 = currentY;
3426 invertedRotateTransform.map( left, currentY - outputPixelOffset, &x1, &y1 );
3427 invertedRotateTransform.map( right, currentY - outputPixelOffset, &x2, &y2 );
3432 std::unique_ptr< QgsAbstractGeometry > intersection( shapeEngine->intersection( &ls ) );
3433 for (
auto it = intersection->const_parts_begin(); it != intersection->const_parts_end(); ++it )
3443 mFillLineSymbol->renderPolyline( QPolygonF() << QPointF( x1, y1 ) << QPointF( x2, y2 ), context.
feature(), context.
renderContext(), -1, useSelectedColor );
3455 map.insert( u
"angle"_s, QString::number( mLineAngle ) );
3456 map.insert( u
"distance"_s, QString::number( mDistance ) );
3457 map.insert( u
"line_width"_s, QString::number( mLineWidth ) );
3459 map.insert( u
"offset"_s, QString::number( mOffset ) );
3475 if ( mFillLineSymbol )
3487 toSld( doc, element, context );
3493 QDomElement symbolizerElem = doc.createElement( u
"se:PolygonSymbolizer"_s );
3494 if ( !props.value( u
"uom"_s, QString() ).toString().isEmpty() )
3495 symbolizerElem.setAttribute( u
"uom"_s, props.value( u
"uom"_s, QString() ).toString() );
3496 element.appendChild( symbolizerElem );
3501 QDomElement fillElem = doc.createElement( u
"se:Fill"_s );
3502 symbolizerElem.appendChild( fillElem );
3504 QDomElement graphicFillElem = doc.createElement( u
"se:GraphicFill"_s );
3505 fillElem.appendChild( graphicFillElem );
3507 QDomElement graphicElem = doc.createElement( u
"se:Graphic"_s );
3508 graphicFillElem.appendChild( graphicElem );
3511 bool exportOk {
false };
3515 if ( !image.isNull() )
3518 QString pngPath { info.completeSuffix().isEmpty() ? context.
exportFilePath() : context.
exportFilePath().chopped( info.completeSuffix().length() ).append( u
"png"_s ) };
3519 pngPath = QgsFileUtils::uniquePath( pngPath );
3520 image.save( pngPath );
3529 QColor lineColor = mFillLineSymbol ? mFillLineSymbol->color() : QColor();
3530 double lineWidth = mFillLineSymbol ? mFillLineSymbol->width() : 0.0;
3538 double angle = props.value( u
"angle"_s, u
"0"_s ).toDouble( &ok );
3541 angleFunc = u
"%1 + %2"_s.arg( props.value( u
"angle"_s, u
"0"_s ).toString() ).arg( mLineAngle );
3545 angleFunc = QString::number(
angle + mLineAngle );
3550 QPointF lineOffset( std::sin( mLineAngle ) * mOffset, std::cos( mLineAngle ) * mOffset );
3559 QString featureStyle;
3560 featureStyle.append(
"Brush(" );
3561 featureStyle.append( u
"fc:%1"_s.arg(
mColor.name() ) );
3562 featureStyle.append( u
",bc:%1"_s.arg(
"#00000000"_L1 ) );
3563 featureStyle.append(
",id:\"ogr-brush-2\"" );
3564 featureStyle.append( u
",a:%1"_s.arg( mLineAngle ) );
3565 featureStyle.append( u
",s:%1"_s.arg( mLineWidth * widthScaleFactor ) );
3566 featureStyle.append(
",dx:0mm" );
3567 featureStyle.append( u
",dy:%1mm"_s.arg( mDistance * widthScaleFactor ) );
3568 featureStyle.append(
')' );
3569 return featureStyle;
3576 && ( !mFillLineSymbol || !mFillLineSymbol->hasDataDefinedProperties() ) )
3601 Qt::PenStyle lineStyle;
3603 QDomElement fillElem = element.firstChildElement( u
"Fill"_s );
3604 if ( fillElem.isNull() )
3607 QDomElement graphicFillElem = fillElem.firstChildElement( u
"GraphicFill"_s );
3608 if ( graphicFillElem.isNull() )
3611 QDomElement graphicElem = graphicFillElem.firstChildElement( u
"Graphic"_s );
3612 if ( graphicElem.isNull() )
3618 if ( name !=
"horline"_L1 )
3626 double d = angleFunc.toDouble( &ok );
3635 offset = std::sqrt( std::pow( vectOffset.x(), 2 ) + std::pow( vectOffset.y(), 2 ) );
3638 double scaleFactor = 1.0;
3639 const QString uom = element.attribute( u
"uom"_s );
3641 size = size * scaleFactor;
3644 auto sl = std::make_unique< QgsLinePatternFillSymbolLayer >();
3645 sl->setOutputUnit( sldUnitSize );
3646 sl->setColor( lineColor );
3648 sl->setLineAngle(
angle );
3650 sl->setDistance( size );
3653 QDomElement strokeElem = element.firstChildElement( u
"Stroke"_s );
3654 if ( !strokeElem.isNull() )
3660 layers.append( l.release() );
3665 return sl.release();
3773 auto layer = std::make_unique< QgsPointPatternFillSymbolLayer >();
3774 if (
properties.contains( u
"distance_x"_s ) )
3776 layer->setDistanceX(
properties[u
"distance_x"_s].toDouble() );
3778 if (
properties.contains( u
"distance_y"_s ) )
3780 layer->setDistanceY(
properties[u
"distance_y"_s].toDouble() );
3782 if (
properties.contains( u
"displacement_x"_s ) )
3784 layer->setDisplacementX(
properties[u
"displacement_x"_s].toDouble() );
3786 if (
properties.contains( u
"displacement_y"_s ) )
3788 layer->setDisplacementY(
properties[u
"displacement_y"_s].toDouble() );
3792 layer->setOffsetX(
properties[u
"offset_x"_s].toDouble() );
3796 layer->setOffsetY(
properties[u
"offset_y"_s].toDouble() );
3799 if (
properties.contains( u
"distance_x_unit"_s ) )
3803 if (
properties.contains( u
"distance_x_map_unit_scale"_s ) )
3807 if (
properties.contains( u
"distance_y_unit"_s ) )
3811 if (
properties.contains( u
"distance_y_map_unit_scale"_s ) )
3815 if (
properties.contains( u
"displacement_x_unit"_s ) )
3819 if (
properties.contains( u
"displacement_x_map_unit_scale"_s ) )
3823 if (
properties.contains( u
"displacement_y_unit"_s ) )
3827 if (
properties.contains( u
"displacement_y_map_unit_scale"_s ) )
3831 if (
properties.contains( u
"offset_x_unit"_s ) )
3835 if (
properties.contains( u
"offset_x_map_unit_scale"_s ) )
3839 if (
properties.contains( u
"offset_y_unit"_s ) )
3843 if (
properties.contains( u
"offset_y_map_unit_scale"_s ) )
3848 if (
properties.contains( u
"random_deviation_x"_s ) )
3850 layer->setMaximumRandomDeviationX(
properties[u
"random_deviation_x"_s].toDouble() );
3852 if (
properties.contains( u
"random_deviation_y"_s ) )
3854 layer->setMaximumRandomDeviationY(
properties[u
"random_deviation_y"_s].toDouble() );
3856 if (
properties.contains( u
"random_deviation_x_unit"_s ) )
3860 if (
properties.contains( u
"random_deviation_x_map_unit_scale"_s ) )
3864 if (
properties.contains( u
"random_deviation_y_unit"_s ) )
3868 if (
properties.contains( u
"random_deviation_y_map_unit_scale"_s ) )
3872 unsigned long seed = 0;
3879 std::random_device rd;
3880 std::mt19937 mt(
static_cast< int >( rd() ) );
3881 std::uniform_int_distribution<> uniformDist( 1, 999999999 );
3882 seed = uniformDist( mt );
3884 layer->setSeed(
seed );
3886 if (
properties.contains( u
"outline_width_unit"_s ) )
3890 if (
properties.contains( u
"outline_width_map_unit_scale"_s ) )
3898 if (
properties.contains( u
"coordinate_reference"_s ) )
3905 layer->setAngle(
properties[u
"angle"_s].toDouble() );
3910 return layer.release();
3915 return u
"PointPatternFill"_s;
3918bool QgsPointPatternFillSymbolLayer::applyPattern(
3919 const QgsSymbolRenderContext &context, QBrush &brush,
double distanceX,
double distanceY,
double displacementX,
double displacementY,
double offsetX,
double offsetY
3930 if ( width > 2000 || height > 2000 )
3932 brush.setTextureImage( QImage() );
3936 QImage patternImage( width, height, QImage::Format_ARGB32 );
3937 patternImage.fill( 0 );
3938 if ( patternImage.isNull() )
3940 brush.setTextureImage( QImage() );
3945 QPainter p( &patternImage );
3948 QgsRenderContext pointRenderContext;
3963 for (
double currentX = -width; currentX <= width * 2.0; currentX += width )
3965 for (
double currentY = -height; currentY <= height * 2.0; currentY += height )
3967 mMarkerSymbol->renderPoint( QPointF( currentX + widthOffset, currentY + heightOffset ), context.
feature(), pointRenderContext );
3976 for (
double currentX = -width; currentX <= width * 2.0; currentX += width )
3978 for (
double currentY = -height / 2.0; currentY <= height * 2.0; currentY += height )
3980 mMarkerSymbol->renderPoint( QPointF( currentX + widthOffset + displacementPixelX, currentY + heightOffset ), context.
feature(), pointRenderContext );
3984 for (
double currentX = -width / 2.0; currentX <= width * 2.0; currentX += width )
3986 for (
double currentY = -height; currentY <= height * 2.0; currentY += height / 2.0 )
3988 mMarkerSymbol->renderPoint( QPointF( currentX + widthOffset + ( std::fmod( currentY, height ) != 0 ? displacementPixelX : 0 ), currentY + heightOffset - displacementPixelY ), context.
feature(), pointRenderContext );
3997 QImage transparentImage = patternImage.copy();
3999 brush.setTextureImage( transparentImage );
4003 brush.setTextureImage( patternImage );
4005 QTransform brushTransform;
4006 brush.setTransform( brushTransform );
4026 if ( !mRenderUsingMarkers )
4071 if ( !useSelectedColor && !mRenderUsingMarkers )
4121 const double widthOffset
4130 const double heightOffset
4151 p->setPen( QPen( Qt::NoPen ) );
4177 std::unique_ptr< QgsPolygon > shapePolygon;
4178 std::unique_ptr< QgsGeometryEngine > shapeEngine;
4185 shapePolygon = std::make_unique< QgsPolygon >();
4187 shapePolygon->setExteriorRing( fromPolygon.release() );
4190 for (
const QPolygonF &ring : *rings )
4193 shapePolygon->addInteriorRing( fromRing.release() );
4197 shapeEngine->prepareGeometry();
4204 path.addPolygon( points );
4207 for (
const QPolygonF &ring : *rings )
4209 path.addPolygon( ring );
4212 p->setClipPath( path, Qt::IntersectClip );
4218 const QRectF boundingRect = points.boundingRect();
4220 QTransform invertedRotateTransform;
4228 QTransform transform;
4229 if ( applyBrushTransform )
4232 transform.translate( -boundingRect.center().x(), -boundingRect.center().y() );
4233 transform.rotate( -
angle );
4234 transform.translate( boundingRect.center().x(), boundingRect.center().y() );
4239 transform.rotate( -
angle );
4242 const QRectF transformedBounds = transform.map( points ).boundingRect();
4243 left = transformedBounds.left() - 2 * width;
4244 top = transformedBounds.top() - 2 * height;
4245 right = transformedBounds.right() + 2 * width;
4246 bottom = transformedBounds.bottom() + 2 * height;
4247 invertedRotateTransform = transform.inverted();
4249 if ( !applyBrushTransform )
4251 left -= transformedBounds.left() - ( width * std::floor( transformedBounds.left() / width ) );
4252 top -= transformedBounds.top() - ( height * std::floor( transformedBounds.top() / height ) );
4257 left = boundingRect.left() - 2 * width;
4258 top = boundingRect.top() - 2 * height;
4259 right = boundingRect.right() + 2 * width;
4260 bottom = boundingRect.bottom() + 2 * height;
4262 if ( !applyBrushTransform )
4264 left -= boundingRect.left() - ( width * std::floor( boundingRect.left() / width ) );
4265 top -= boundingRect.top() - ( height * std::floor( boundingRect.top() / height ) );
4283 ? ( maxRandomDeviationX * width / 100 )
4293 ? ( maxRandomDeviationY * height / 100 )
4296 std::random_device rd;
4297 std::mt19937 mt(
seed == 0 ? rd() :
seed );
4298 std::uniform_real_distribution<> uniformDist( 0, 1 );
4304 const bool needsExpressionContext =
mMarkerSymbol->hasDataDefinedProperties();
4312 bool alternateColumn =
false;
4313 int currentCol = -3;
4314 for (
double currentX = left; currentX <= right; currentX += width, alternateColumn = !alternateColumn )
4319 if ( needsExpressionContext )
4322 bool alternateRow =
false;
4323 const double columnX = currentX + widthOffset;
4324 int currentRow = -3;
4325 for (
double currentY = top; currentY <= bottom; currentY += height, alternateRow = !alternateRow )
4330 double y = currentY + heightOffset;
4333 x += displacementPixelX;
4335 if ( !alternateColumn )
4336 y -= displacementPixelY;
4342 invertedRotateTransform.map( xx, yy, &x, &y );
4345 if ( useRandomShift )
4347 x += ( 2 * uniformDist( mt ) - 1 ) * maxRandomDeviationPixelX;
4348 y += ( 2 * uniformDist( mt ) - 1 ) * maxRandomDeviationPixelY;
4351 if ( needsExpressionContext )
4359 bool renderPoint =
true;
4367 renderPoint = shapeEngine->intersects( &p );
4379 renderPoint = shapeEngine->contains( markerBounds.
constGet() );
4381 renderPoint = shapeEngine->intersects( markerBounds.
constGet() );
4407 map.insert( u
"distance_x"_s, QString::number(
mDistanceX ) );
4408 map.insert( u
"distance_y"_s, QString::number(
mDistanceY ) );
4409 map.insert( u
"displacement_x"_s, QString::number(
mDisplacementX ) );
4410 map.insert( u
"displacement_y"_s, QString::number(
mDisplacementY ) );
4411 map.insert( u
"offset_x"_s, QString::number(
mOffsetX ) );
4412 map.insert( u
"offset_y"_s, QString::number(
mOffsetY ) );
4434 map.insert( u
"seed"_s, QString::number(
mSeed ) );
4435 map.insert( u
"angle"_s,
mAngle );
4455 toSld( doc, element, context );
4461 for (
int symbolLayerIdx = 0; symbolLayerIdx <
mMarkerSymbol->symbolLayerCount(); symbolLayerIdx++ )
4463 QDomElement symbolizerElem = doc.createElement( u
"se:PolygonSymbolizer"_s );
4464 if ( !props.value( u
"uom"_s, QString() ).toString().isEmpty() )
4465 symbolizerElem.setAttribute( u
"uom"_s, props.value( u
"uom"_s, QString() ).toString() );
4466 element.appendChild( symbolizerElem );
4471 QDomElement fillElem = doc.createElement( u
"se:Fill"_s );
4472 symbolizerElem.appendChild( fillElem );
4474 QDomElement graphicFillElem = doc.createElement( u
"se:GraphicFill"_s );
4475 fillElem.appendChild( graphicFillElem );
4480 bool exportOk {
false };
4484 if ( !image.isNull() )
4486 QDomElement graphicElem = doc.createElement( u
"se:Graphic"_s );
4487 graphicFillElem.appendChild( graphicElem );
4489 QString pngPath { info.completeSuffix().isEmpty() ? context.
exportFilePath() : context.
exportFilePath().chopped( info.completeSuffix().length() ).append( u
"png"_s ) };
4490 pngPath = QgsFileUtils::uniquePath( pngPath );
4491 image.save( pngPath );
4510 symbolizerElem.appendChild( graphicMarginElem );
4514 markerLayer->writeSldMarker( doc, graphicFillElem, context );
4522 QgsDebugError( u
"Missing point pattern symbol layer. Skip it."_s );
4531 double angleRads { qDegreesToRadians(
mAngle ) };
4540 if ( displacementXPx != 0 )
4545 if ( displacementYPx != 0 )
4552 QPixmap pixmap( size );
4553 pixmap.fill( Qt::transparent );
4555 painter.begin( &pixmap );
4556 painter.setRenderHint( QPainter::Antialiasing );
4564 std::unique_ptr< QgsPointPatternFillSymbolLayer > layerClone(
clone() );
4566 layerClone->setAngle( qRadiansToDegrees( angleRads ) );
4569 layerClone->setMaximumRandomDeviationX( 0 );
4570 layerClone->setMaximumRandomDeviationY( 0 );
4572 layerClone->drawPreviewIcon( symbolContext, pixmap.size() );
4574 return pixmap.toImage();
4581 QDomElement fillElem = element.firstChildElement( u
"Fill"_s );
4582 if ( fillElem.isNull() )
4585 QDomElement graphicFillElem = fillElem.firstChildElement( u
"GraphicFill"_s );
4586 if ( graphicFillElem.isNull() )
4589 QDomElement graphicElem = graphicFillElem.firstChildElement( u
"Graphic"_s );
4590 if ( graphicElem.isNull() )
4594 if ( !simpleMarkerSl )
4598 layers.append( simpleMarkerSl.release() );
4600 auto marker = std::make_unique< QgsMarkerSymbol >( layers );
4603 const double markerSize { marker->size() };
4605 auto pointPatternFillSl = std::make_unique< QgsPointPatternFillSymbolLayer >();
4606 pointPatternFillSl->setSubSymbol( marker.release() );
4611 auto distanceParser = [&](
const QStringList &values ) {
4612 switch ( values.count() )
4617 const double v { values.at( 0 ).toDouble( &ok ) };
4620 pointPatternFillSl->setDistanceX( v * 2 + markerSize );
4621 pointPatternFillSl->setDistanceY( v * 2 + markerSize );
4628 const double vX { values.at( 1 ).toDouble( &ok ) };
4631 pointPatternFillSl->setDistanceX( vX * 2 + markerSize );
4633 const double vY { values.at( 0 ).toDouble( &ok ) };
4636 pointPatternFillSl->setDistanceY( vY * 2 + markerSize );
4643 const double vX { values.at( 1 ).toDouble( &ok ) };
4646 pointPatternFillSl->setDistanceX( vX * 2 + markerSize );
4648 const double vYt { values.at( 0 ).toDouble( &ok ) };
4651 const double vYb { values.at( 2 ).toDouble( &ok ) };
4654 pointPatternFillSl->setDistanceY( ( vYt + vYb ) + markerSize );
4662 const double vYt { values.at( 0 ).toDouble( &ok ) };
4665 const double vYb { values.at( 2 ).toDouble( &ok ) };
4668 pointPatternFillSl->setDistanceY( ( vYt + vYb ) + markerSize );
4671 const double vXr { values.at( 1 ).toDouble( &ok ) };
4674 const double vXl { values.at( 3 ).toDouble( &ok ) };
4677 pointPatternFillSl->setDistanceX( ( vXr + vXl ) + markerSize );
4688 bool distanceFromVendorOption {
false };
4690 for ( QgsStringMap::iterator it = vendorOptions.begin(); it != vendorOptions.end(); ++it )
4693 if ( it.key() ==
"distance"_L1 )
4695 distanceParser( it.value().split(
',' ) );
4696 distanceFromVendorOption =
true;
4699 else if ( it.key() ==
"graphic-margin"_L1 )
4701 distanceParser( it.value().split(
' ' ) );
4702 distanceFromVendorOption =
true;
4707 if ( !distanceFromVendorOption && !graphicFillElem.elementsByTagName( u
"Size"_s ).isEmpty() )
4709 const QDomElement sizeElement { graphicFillElem.elementsByTagName( u
"Size"_s ).at( 0 ).toElement() };
4711 const double size { sizeElement.text().toDouble( &ok ) };
4714 pointPatternFillSl->setDistanceX( size );
4715 pointPatternFillSl->setDistanceY( size );
4719 return pointPatternFillSl.release();
4804 attributes.unite(
mMarkerSymbol->usedAttributes( context ) );
4842 auto sl = std::make_unique< QgsCentroidFillSymbolLayer >();
4844 if (
properties.contains( u
"point_on_surface"_s ) )
4845 sl->setPointOnSurface(
properties[u
"point_on_surface"_s].toInt() != 0 );
4846 if (
properties.contains( u
"point_on_all_parts"_s ) )
4847 sl->setPointOnAllParts(
properties[u
"point_on_all_parts"_s].toInt() != 0 );
4848 if (
properties.contains( u
"clip_points"_s ) )
4849 sl->setClipPoints(
properties[u
"clip_points"_s].toInt() != 0 );
4850 if (
properties.contains( u
"clip_on_current_part_only"_s ) )
4851 sl->setClipOnCurrentPartOnly(
properties[u
"clip_on_current_part_only"_s].toInt() != 0 );
4853 sl->restoreOldDataDefinedProperties(
properties );
4855 return sl.release();
4860 return u
"CentroidFill"_s;
4888 part.exterior = points;
4890 part.rings = *rings;
4898 mCurrentParts << part;
4903 const double prevOpacity =
mMarker->opacity();
4907 mMarker->setOpacity( prevOpacity );
4916 mCurrentParts.clear();
4923 const double prevOpacity =
mMarker->opacity();
4929 mMarker->setOpacity( prevOpacity );
4934void QgsCentroidFillSymbolLayer::render(
QgsRenderContext &context,
const QVector<QgsCentroidFillSymbolLayer::Part> &parts,
const QgsFeature &feature,
bool selected )
4943 QVector< QgsGeometry > geometryParts;
4944 geometryParts.reserve( parts.size() );
4945 QPainterPath globalPath;
4948 int maxAreaPartIdx = 0;
4950 for (
int i = 0; i < parts.size(); i++ )
4952 const Part part = parts[i];
4955 if ( !geom.
isNull() && !part.rings.empty() )
4961 int area = poly->
area();
4963 if ( area > maxArea )
4973 globalPath.addPolygon( part.exterior );
4974 for (
const QPolygonF &ring : part.rings )
4976 globalPath.addPolygon( ring );
4981 for (
int i = 0; i < parts.size(); i++ )
4986 const Part part = parts[i];
4994 path.addPolygon( part.exterior );
4995 for (
const QPolygonF &ring : part.rings )
4997 path.addPolygon( ring );
5006 context.
painter()->setClipPath( path );
5013 mMarker->renderPoint( centroid, feature.
isValid() ? &feature :
nullptr, context, -1, selected );
5028 map[u
"clip_points"_s] = QString::number(
mClipPoints );
5035 auto x = std::make_unique< QgsCentroidFillSymbolLayer >();
5038 x->setSubSymbol(
mMarker->clone() );
5051 toSld( doc, element, context );
5059 return mMarker->toSld( doc, element, context );
5069 layers.append( l.release() );
5070 auto marker = std::make_unique<QgsMarkerSymbol>( layers );
5072 auto sl = std::make_unique< QgsCentroidFillSymbolLayer >();
5073 sl->setSubSymbol( marker.release() );
5074 sl->setPointOnAllParts(
false );
5075 return sl.release();
5102 attributes.unite(
mMarker->usedAttributes( context ) );
5125 mMarker->setOutputUnit( unit );
5142 return mMarker->usesMapUnits();
5151 mMarker->setMapUnitScale( scale );
5159 return mMarker->mapUnitScale();
5186 imagePath =
properties[u
"imageFile"_s].toString();
5188 if (
properties.contains( u
"coordinate_mode"_s ) )
5208 auto symbolLayer = std::make_unique< QgsRasterFillSymbolLayer >( imagePath );
5209 symbolLayer->setCoordinateMode( mode );
5210 symbolLayer->setOpacity( alpha );
5211 symbolLayer->setOffset(
offset );
5212 symbolLayer->setAngle(
angle );
5213 symbolLayer->setWidth(
width );
5214 if (
properties.contains( u
"offset_unit"_s ) )
5218 if (
properties.contains( u
"offset_map_unit_scale"_s ) )
5222 if (
properties.contains( u
"width_unit"_s ) )
5226 if (
properties.contains( u
"width_map_unit_scale"_s ) )
5233 symbolLayer->setHeight(
properties[u
"height"_s].toDouble() );
5236 symbolLayer->restoreOldDataDefinedProperties(
properties );
5238 return symbolLayer.release();
5243 QDomElement fillElem = element.firstChildElement( u
"Fill"_s );
5244 if ( fillElem.isNull() )
5247 QDomElement graphicFillElem = fillElem.firstChildElement( u
"GraphicFill"_s );
5248 if ( graphicFillElem.isNull() )
5251 QDomElement graphicElem = graphicFillElem.firstChildElement( u
"Graphic"_s );
5252 if ( graphicElem.isNull() )
5255 QString path, mimeType;
5263 if ( !QFile::exists( path ) )
5268 auto sl = std::make_unique< QgsRasterFillSymbolLayer>( path );
5270 return sl.release();
5275 QVariantMap::iterator it =
properties.find( u
"imageFile"_s );
5279 it.value() = pathResolver.
writePath( it.value().toString() );
5281 it.value() = pathResolver.
readPath( it.value().toString() );
5293 return u
"RasterFill"_s;
5309 QPointF
offset = mOffset;
5327 QRectF boundingRect = points.boundingRect();
5328 mBrush.setTransform(
mBrush.transform().translate( boundingRect.left() -
mBrush.transform().dx(), boundingRect.top() -
mBrush.transform().dy() ) );
5340 applyPattern(
mBrush, mImageFilePath, mWidth, mHeight, mOpacity * context.
opacity(), context );
5351 map[u
"imageFile"_s] = mImageFilePath;
5352 map[u
"coordinate_mode"_s] = QString::number(
static_cast< int >( mCoordinateMode ) );
5353 map[u
"alpha"_s] = QString::number( mOpacity );
5357 map[u
"angle"_s] = QString::number(
mAngle );
5359 map[u
"width"_s] = QString::number( mWidth );
5360 map[u
"height"_s] = QString::number( mHeight );
5369 auto sl = std::make_unique< QgsRasterFillSymbolLayer >( mImageFilePath );
5370 sl->setCoordinateMode( mCoordinateMode );
5371 sl->setOpacity( mOpacity );
5372 sl->setOffset( mOffset );
5373 sl->setOffsetUnit( mOffsetUnit );
5374 sl->setOffsetMapUnitScale( mOffsetMapUnitScale );
5376 sl->setWidth( mWidth );
5377 sl->setHeight( mHeight );
5378 sl->setSizeUnit( mSizeUnit );
5379 sl->setSizeMapUnitScale( mSizeMapUnitScale );
5382 return sl.release();
5387 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();
5565 brush.setTextureImage( img );
5574 : mCountMethod( method )
5590 unsigned long seed = 0;
5597 std::random_device rd;
5598 std::mt19937 mt(
static_cast< int >( rd() ) );
5599 std::uniform_int_distribution<> uniformDist( 1, 999999999 );
5600 seed = uniformDist( mt );
5605 if (
properties.contains( u
"density_area_unit"_s ) )
5607 if (
properties.contains( u
"density_area_unit_scale"_s ) )
5610 if (
properties.contains( u
"clip_points"_s ) )
5612 sl->setClipPoints(
properties[u
"clip_points"_s].toInt() );
5615 return sl.release();
5620 return u
"RandomMarkerFill"_s;
5625 mMarker->setColor(
color );
5631 return mMarker ? mMarker->color() :
mColor;
5648 part.exterior = points;
5650 part.rings = *rings;
5652 if ( mRenderingFeature )
5656 mFeatureSymbolOpacity = context.
opacity();
5657 mCurrentParts << part;
5662 const double prevOpacity = mMarker->opacity();
5663 mMarker->setOpacity( mMarker->opacity() * context.
opacity() );
5666 mMarker->setOpacity( prevOpacity );
5670void QgsRandomMarkerFillSymbolLayer::render(
QgsRenderContext &context,
const QVector<QgsRandomMarkerFillSymbolLayer::Part> &parts,
const QgsFeature &feature,
bool selected )
5679 QVector< QgsGeometry > geometryParts;
5680 geometryParts.reserve( parts.size() );
5683 for (
const Part &part : parts )
5686 if ( !geom.
isNull() && !part.rings.empty() )
5689 for (
const QPolygonF &ring : part.rings )
5697 geom = geom.
buffer( 0, 0 );
5699 geometryParts << geom;
5703 path.addPolygon( part.exterior );
5704 for (
const QPolygonF &ring : part.rings )
5706 path.addPolygon( ring );
5711 const QgsGeometry geom = geometryParts.count() != 1 ?
QgsGeometry::unaryUnion( geometryParts ) : geometryParts.at( 0 );
5716 context.
painter()->setClipPath( path );
5720 int count = mPointCount;
5723 context.expressionContext().setOriginalValueVariable( count );
5724 count = mDataDefinedProperties.valueAsInt( QgsSymbolLayer::Property::PointCount, context.expressionContext(), count );
5727 switch ( mCountMethod )
5739 count = std::max( 0.0, std::ceil( count * ( geom.
area() /
densityArea ) ) );
5746 unsigned long seed = mSeed;
5749 context.expressionContext().setOriginalValueVariable( static_cast< unsigned long long >( seed ) );
5750 seed = mDataDefinedProperties.valueAsInt( QgsSymbolLayer::Property::RandomSeed, context.expressionContext(), seed );
5757 std::sort( randomPoints.begin(), randomPoints.end(), [](
const QgsPointXY & a,
const QgsPointXY & b )->bool
5759 return a.y() < b.y();
5762 QgsExpressionContextScope *scope =
new QgsExpressionContextScope();
5763 QgsExpressionContextScopePopper scopePopper( context.
expressionContext(), scope );
5765 const bool needsExpressionContext = mMarker->hasDataDefinedProperties();
5770 for (
const QgsPointXY &p : std::as_const( randomPoints ) )
5772 if ( needsExpressionContext )
5774 mMarker->renderPoint( QPointF( p.x(), p.y() ), feature.
isValid() ? &feature :
nullptr, context, -1, selected );
5788 map.insert( u
"count_method"_s, QString::number(
static_cast< int >( mCountMethod ) ) );
5789 map.insert( u
"point_count"_s, QString::number( mPointCount ) );
5790 map.insert( u
"density_area"_s, QString::number( mDensityArea ) );
5793 map.insert( u
"seed"_s, QString::number( mSeed ) );
5794 map.insert( u
"clip_points"_s, QString::number( mClipPoints ) );
5800 auto res = std::make_unique< QgsRandomMarkerFillSymbolLayer >( mPointCount, mCountMethod, mDensityArea, mSeed );
5803 res->setDensityAreaUnit( mDensityAreaUnit );
5804 res->setDensityAreaUnitScale( mDensityAreaUnitScale );
5805 res->mClipPoints = mClipPoints;
5806 res->setSubSymbol( mMarker->clone() );
5808 return res.release();
5831 return mMarker.get();
5843 mColor = mMarker->color();
5852 attributes.unite( mMarker->usedAttributes( context ) );
5861 if ( mMarker && mMarker->hasDataDefinedProperties() )
5898 return mCountMethod;
5903 mCountMethod = method;
5908 return mDensityArea;
5913 mDensityArea = area;
5920 mRenderingFeature =
true;
5921 mCurrentParts.clear();
5926 mRenderingFeature =
false;
5928 const double prevOpacity = mMarker->opacity();
5929 mMarker->setOpacity( mMarker->opacity() * mFeatureSymbolOpacity );
5931 render( context, mCurrentParts, feature,
false );
5933 mFeatureSymbolOpacity = 1;
5934 mMarker->setOpacity( prevOpacity );
5942 mDensityAreaUnit = unit;
5945 mMarker->setOutputUnit( unit );
5953 return mMarker->outputUnit();
5962 return mMarker->usesMapUnits();
5971 mMarker->setMapUnitScale( scale );
5979 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(), Qgis::StringFormat format=Qgis::StringFormat::PlainText)
Adds a message to the log instance (and creates it if necessary).
Resolves relative paths into absolute paths and vice versa.
QString writePath(const QString &filename) const
Prepare a filename to save it to the project file.
QString readPath(const QString &filename) const
Turn filename read from the project file to an absolute path.
QgsMapUnitScale mapUnitScale() const override
QgsMapUnitScale mDisplacementYMapUnitScale
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
QgsMapUnitScale mDisplacementXMapUnitScale
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
double distanceX() const
Returns the horizontal distance between rendered markers in the fill.
QgsMapUnitScale mDistanceYMapUnitScale
QImage toTiledPatternImage() const override
Renders the symbol layer as an image that can be used as a seamless pattern fill for polygons,...
double displacementY() const
Returns the vertical displacement for odd numbered columns in the pattern.
void setColor(const QColor &c) override
Sets the "representative" color for the symbol layer.
Qgis::RenderUnit mDistanceXUnit
void startFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called before the layer will be rendered for a particular feature.
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)
void copyCommonProperties(QgsSymbolLayer *destLayer) const
Copies all common base class properties from this layer to another symbol layer.
virtual bool setSubSymbol(QgsSymbol *symbol)
Sets layer's subsymbol. takes ownership of the passed symbol.
bool shouldRenderUsingSelectionColor(const QgsSymbolRenderContext &context) const
Returns true if the symbol layer should be rendered using the selection color from the render context...
Qgis::SymbolType type() const
virtual QColor fillColor() const
Returns the fill color for the symbol layer.
static const bool SELECTION_IS_OPAQUE
Whether styles for selected features ignore symbol alpha.
bool installMasks(QgsRenderContext &context, bool recursive, const QRectF &rect=QRectF())
When rendering, install masks on context painter.
void removeMasks(QgsRenderContext &context, bool recursive)
When rendering, remove previously installed masks from context painter if recursive is true masks are...
virtual QSet< QString > usedAttributes(const QgsRenderContext &context) const
Returns the set of attributes referenced by the layer.
@ GradientType
Gradient fill type.
@ SecondaryColor
Secondary color (eg for gradient fills).
@ File
Filename, eg for svg files.
@ GradientReference2Y
Gradient reference point 2 y.
@ GradientReference1X
Gradient reference point 1 x.
@ OffsetY
Vertical offset.
@ OffsetX
Horizontal offset.
@ GradientReference1Y
Gradient reference point 1 y.
@ GradientSpread
Gradient spread mode.
@ ShapeburstMaxDistance
Shapeburst fill from edge distance.
@ StrokeStyle
Stroke style (eg solid, dashed).
@ DistanceY
Vertical distance between points.
@ DensityArea
Density area.
@ ClipPoints
Whether markers should be clipped to polygon boundaries.
@ LineClipping
Line clipping mode.
@ ShapeburstIgnoreRings
Shapeburst ignore rings.
@ ShapeburstUseWholeShape
Shapeburst use whole shape.
@ DisplacementX
Horizontal displacement.
@ CoordinateMode
Gradient coordinate mode.
@ FillStyle
Fill style (eg solid, dots).
@ GradientReference2X
Gradient reference point 2 x.
@ StrokeColor
Stroke color.
@ BlurRadius
Shapeburst blur radius.
@ MarkerClipping
Marker clipping mode.
@ RandomSeed
Random number seed.
@ LineAngle
Line angle, or angle of hash lines for hash line symbols.
@ JoinStyle
Line join style.
@ RandomOffsetY
Random offset Y.
@ DisplacementY
Vertical displacement.
@ DistanceX
Horizontal distance between points.
@ GradientReference1IsCentroid
Gradient reference point 1 is centroid.
@ StrokeWidth
Stroke width.
@ GradientReference2IsCentroid
Gradient reference point 2 is centroid.
@ LineDistance
Distance between lines, or length of lines for hash line symbols.
@ RandomOffsetX
Random offset X.
void restoreOldDataDefinedProperties(const QVariantMap &stringMap)
Restores older data defined properties from string map.
virtual double estimateMaxBleed(const QgsRenderContext &context) const
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
static const bool SELECT_FILL_BORDER
Whether fill styles for selected features also highlight symbol stroke.
virtual bool rendersIdenticallyTo(const QgsSymbolLayer *other) const
Returns true if this symbol layer will always render identically to an other symbol layer.
virtual QString layerType() const =0
Returns a string that represents this layer type.
virtual QColor color() const
Returns the "representative" color of the symbol layer.
virtual QColor strokeColor() const
Returns the stroke color for the symbol layer.
virtual Qgis::SymbolLayerFlags flags() const
Returns flags which control the symbol layer's behavior.
QgsPropertyCollection mDataDefinedProperties
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the symbol layer's property collection, used for data defined overrides.
static const bool SELECT_FILL_STYLE
Whether fill styles for selected features uses symbol layer style.
virtual bool hasDataDefinedProperties() const
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
QgsSymbolLayer(const QgsSymbolLayer &other)
Encapsulates the context in which a symbol is being rendered.
const QgsFeature * feature() const
Returns the current feature being rendered.
QgsFields fields() const
Fields of the layer.
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for data defined symbology.
bool forceVectorRendering() const
Returns true if symbol must be rendered using vector methods, and optimisations like pre-rendered ima...
qreal opacity() const
Returns the opacity for the symbol.
QgsRenderContext & renderContext()
Returns a reference to the context's render context.
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.