44#include <QSvgRenderer>
45#include <QDomDocument>
55 Qt::PenJoinStyle penJoinStyle )
56 : mBrushStyle( style )
57 , mStrokeColor( strokeColor )
58 , mStrokeStyle( strokeStyle )
59 , mStrokeWidth( strokeWidth )
60 , mPenJoinStyle( penJoinStyle )
78 return Qgis::RenderUnit::Unknown;
104void QgsSimpleFillSymbolLayer::applyDataDefinedSymbology(
QgsSymbolRenderContext &context, QBrush &brush, QPen &pen, QPen &selPen )
129 penColor.setAlphaF( context.
opacity() * penColor.alphaF() );
130 pen.setColor( penColor );
138 double width = exprVal.toDouble( &ok );
142 pen.setWidthF( width );
143 selPen.setWidthF( width );
180 if ( props.contains( QStringLiteral(
"color" ) ) )
182 if ( props.contains( QStringLiteral(
"style" ) ) )
184 if ( props.contains( QStringLiteral(
"color_border" ) ) )
189 else if ( props.contains( QStringLiteral(
"outline_color" ) ) )
193 else if ( props.contains( QStringLiteral(
"line_color" ) ) )
198 if ( props.contains( QStringLiteral(
"style_border" ) ) )
203 else if ( props.contains( QStringLiteral(
"outline_style" ) ) )
207 else if ( props.contains( QStringLiteral(
"line_style" ) ) )
211 if ( props.contains( QStringLiteral(
"width_border" ) ) )
214 strokeWidth = props[QStringLiteral(
"width_border" )].toDouble();
216 else if ( props.contains( QStringLiteral(
"outline_width" ) ) )
218 strokeWidth = props[QStringLiteral(
"outline_width" )].toDouble();
220 else if ( props.contains( QStringLiteral(
"line_width" ) ) )
222 strokeWidth = props[QStringLiteral(
"line_width" )].toDouble();
224 if ( props.contains( QStringLiteral(
"offset" ) ) )
226 if ( props.contains( QStringLiteral(
"joinstyle" ) ) )
231 if ( props.contains( QStringLiteral(
"border_width_unit" ) ) )
235 else if ( props.contains( QStringLiteral(
"outline_width_unit" ) ) )
239 else if ( props.contains( QStringLiteral(
"line_width_unit" ) ) )
243 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
246 if ( props.contains( QStringLiteral(
"border_width_map_unit_scale" ) ) )
248 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
251 sl->restoreOldDataDefinedProperties( props );
259 return QStringLiteral(
"SimpleFill" );
271 selColor.setAlphaF( context.
opacity() );
329 if (
mBrush.style() == Qt::SolidPattern ||
mBrush.style() == Qt::NoBrush || !
dynamic_cast<QPrinter *
>( p->device() ) )
343 p->setPen( Qt::NoPen );
347 p->setBrush( Qt::NoBrush );
365 map[QStringLiteral(
"outline_width" )] = QString::number(
mStrokeWidth );
393 QDomElement symbolizerElem = doc.createElement( QStringLiteral(
"se:PolygonSymbolizer" ) );
394 if ( !props.value( QStringLiteral(
"uom" ), QString() ).toString().isEmpty() )
395 symbolizerElem.setAttribute( QStringLiteral(
"uom" ), props.value( QStringLiteral(
"uom" ), QString() ).toString() );
396 element.appendChild( symbolizerElem );
405 bool exportOk {
false };
409 if ( ! image.isNull() )
412 QDomElement fillElem = doc.createElement( QStringLiteral(
"se:Fill" ) );
413 symbolizerElem.appendChild( fillElem );
414 QDomElement graphicFillElem = doc.createElement( QStringLiteral(
"se:GraphicFill" ) );
415 fillElem.appendChild( graphicFillElem );
416 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
417 graphicFillElem.appendChild( graphicElem );
419 const QFileInfo info { context.exportFilePath() };
420 QString pngPath { info.completeSuffix().isEmpty() ? context.exportFilePath() : context.exportFilePath().chopped( info.completeSuffix().length() ).append( QStringLiteral(
"png" ) ) };
422 image.save( pngPath );
437 const double alpha { props.value( QStringLiteral(
"alpha" ), QVariant() ).toDouble( &ok ) };
443 QDomElement fillElem = doc.createElement( QStringLiteral(
"se:Fill" ) );
444 symbolizerElem.appendChild( fillElem );
451 QDomElement strokeElem = doc.createElement( QStringLiteral(
"se:Stroke" ) );
452 symbolizerElem.appendChild( strokeElem );
456 const double alpha { props.value( QStringLiteral(
"alpha" ), QVariant() ).toDouble( &ok ) };
476 symbolStyle.append(
';' );
485 Qt::BrushStyle fillStyle;
489 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
492 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
498 double scaleFactor = 1.0;
499 const QString uom = element.attribute( QStringLiteral(
"uom" ) );
506 sl->setOutputUnit( sldUnitSize );
515 return penBleed + offsetBleed;
573 QPixmap pixmap( QSize( 32, 32 ) );
574 pixmap.fill( Qt::transparent );
576 painter.begin( &pixmap );
577 painter.setRenderHint( QPainter::Antialiasing );
583 QgsSymbolRenderContext symbolContext( renderContext, Qgis::RenderUnit::Pixels, 1.0,
false, Qgis::SymbolRenderHints() );
585 std::unique_ptr< QgsSimpleFillSymbolLayer > layerClone(
clone() );
586 layerClone->setStrokeStyle( Qt::PenStyle::NoPen );
587 layerClone->drawPreviewIcon( symbolContext, pixmap.size() );
589 return pixmap.toImage();
597 : mGradientColorType( colorType )
598 , mGradientType( gradientType )
599 , mCoordinateMode( coordinateMode )
600 , mGradientSpread( spread )
601 , mReferencePoint1( QPointF( 0.5, 0 ) )
602 , mReferencePoint2( QPointF( 0.5, 1 ) )
623 bool refPoint1IsCentroid =
false;
625 bool refPoint2IsCentroid =
false;
630 if ( props.contains( QStringLiteral(
"type" ) ) )
632 if ( props.contains( QStringLiteral(
"coordinate_mode" ) ) )
634 if ( props.contains( QStringLiteral(
"spread" ) ) )
636 if ( props.contains( QStringLiteral(
"color_type" ) ) )
638 if ( props.contains( QStringLiteral(
"gradient_color" ) ) )
643 else if ( props.contains( QStringLiteral(
"color" ) ) )
647 if ( props.contains( QStringLiteral(
"gradient_color2" ) ) )
652 if ( props.contains( QStringLiteral(
"reference_point1" ) ) )
654 if ( props.contains( QStringLiteral(
"reference_point1_iscentroid" ) ) )
655 refPoint1IsCentroid = props[QStringLiteral(
"reference_point1_iscentroid" )].toInt();
656 if ( props.contains( QStringLiteral(
"reference_point2" ) ) )
658 if ( props.contains( QStringLiteral(
"reference_point2_iscentroid" ) ) )
659 refPoint2IsCentroid = props[QStringLiteral(
"reference_point2_iscentroid" )].toInt();
660 if ( props.contains( QStringLiteral(
"angle" ) ) )
661 angle = props[QStringLiteral(
"angle" )].toDouble();
663 if ( props.contains( QStringLiteral(
"offset" ) ) )
680 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
682 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
685 sl->setReferencePoint1IsCentroid( refPoint1IsCentroid );
687 sl->setReferencePoint2IsCentroid( refPoint2IsCentroid );
688 sl->setAngle(
angle );
690 sl->setColorRamp( gradientRamp );
692 sl->restoreOldDataDefinedProperties( props );
705 return QStringLiteral(
"GradientFill" );
708void QgsGradientFillSymbolLayer::applyDataDefinedSymbology(
QgsSymbolRenderContext &context,
const QPolygonF &points )
753 if ( currentType == QObject::tr(
"linear" ) )
757 else if ( currentType == QObject::tr(
"radial" ) )
761 else if ( currentType == QObject::tr(
"conical" ) )
775 if ( currentCoordMode == QObject::tr(
"feature" ) )
779 else if ( currentCoordMode == QObject::tr(
"viewport" ) )
793 if ( currentSpread == QObject::tr(
"pad" ) )
797 else if ( currentSpread == QObject::tr(
"repeat" ) )
801 else if ( currentSpread == QObject::tr(
"reflect" ) )
848 if ( refPoint1IsCentroid || refPoint2IsCentroid )
853 QRectF bbox = points.boundingRect();
854 double centroidX = (
centroid.
x() - bbox.left() ) / bbox.width();
855 double centroidY = (
centroid.
y() - bbox.top() ) / bbox.height();
857 if ( refPoint1IsCentroid )
859 refPoint1X = centroidX;
860 refPoint1Y = centroidY;
862 if ( refPoint2IsCentroid )
864 refPoint2X = centroidX;
865 refPoint2Y = centroidY;
871 spread, QPointF( refPoint1X, refPoint1Y ), QPointF( refPoint2X, refPoint2Y ),
angle );
874QPointF QgsGradientFillSymbolLayer::rotateReferencePoint( QPointF refPoint,
double angle )
879 QLineF refLine = QLineF( QPointF( 0.5, 0.5 ), refPoint );
881 refLine.setAngle( refLine.angle() +
angle );
883 QPointF rotatedReferencePoint = refLine.p2();
885 if ( rotatedReferencePoint.x() > 1 )
886 rotatedReferencePoint.setX( 1 );
887 if ( rotatedReferencePoint.x() < 0 )
888 rotatedReferencePoint.setX( 0 );
889 if ( rotatedReferencePoint.y() > 1 )
890 rotatedReferencePoint.setY( 1 );
891 if ( rotatedReferencePoint.y() < 0 )
892 rotatedReferencePoint.setY( 0 );
894 return rotatedReferencePoint;
901 QPointF referencePoint1, QPointF referencePoint2,
const double angle )
906 QColor fillColor2 =
color2;
907 fillColor2.setAlphaF( context.
opacity() * fillColor2.alphaF() );
918 gradient = QLinearGradient( rotatedReferencePoint1, rotatedReferencePoint2 );
921 gradient = QRadialGradient( rotatedReferencePoint1, QLineF( rotatedReferencePoint1, rotatedReferencePoint2 ).length() );
924 gradient = QConicalGradient( rotatedReferencePoint1, QLineF( rotatedReferencePoint1, rotatedReferencePoint2 ).
angle() );
930 gradient.setCoordinateMode( QGradient::ObjectBoundingMode );
933 gradient.setCoordinateMode( QGradient::StretchToDeviceMode );
939 gradient.setSpread( QGradient::PadSpread );
942 gradient.setSpread( QGradient::ReflectSpread );
945 gradient.setSpread( QGradient::RepeatSpread );
961 gradient.setColorAt( 1.0, fillColor2 );
965 brush = QBrush( gradient );
972 selColor.setAlphaF( context.
opacity() );
989 applyDataDefinedSymbology( context, points );
992 p->setPen( Qt::NoPen );
1025 map[QStringLiteral(
"color_type" )] = QString::number(
static_cast< int >(
mGradientColorType ) );
1026 map[QStringLiteral(
"type" )] = QString::number(
static_cast<int>(
mGradientType ) );
1027 map[QStringLiteral(
"coordinate_mode" )] = QString::number(
static_cast< int >(
mCoordinateMode ) );
1028 map[QStringLiteral(
"spread" )] = QString::number(
static_cast< int >(
mGradientSpread ) );
1033 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
1039#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
1063 return sl.release();
1105 int blurRadius,
bool useWholeShape,
double maxDistance )
1106 : mBlurRadius( blurRadius )
1107 , mUseWholeShape( useWholeShape )
1108 , mMaxDistance( maxDistance )
1109 , mColorType( colorType )
1128 if ( props.contains( QStringLiteral(
"color_type" ) ) )
1132 if ( props.contains( QStringLiteral(
"shapeburst_color" ) ) )
1137 else if ( props.contains( QStringLiteral(
"color" ) ) )
1142 if ( props.contains( QStringLiteral(
"shapeburst_color2" ) ) )
1147 else if ( props.contains( QStringLiteral(
"gradient_color2" ) ) )
1151 if ( props.contains( QStringLiteral(
"blur_radius" ) ) )
1153 blurRadius = props[QStringLiteral(
"blur_radius" )].toInt();
1155 if ( props.contains( QStringLiteral(
"use_whole_shape" ) ) )
1157 useWholeShape = props[QStringLiteral(
"use_whole_shape" )].toInt();
1159 if ( props.contains( QStringLiteral(
"max_distance" ) ) )
1161 maxDistance = props[QStringLiteral(
"max_distance" )].toDouble();
1163 if ( props.contains( QStringLiteral(
"offset" ) ) )
1182 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
1186 if ( props.contains( QStringLiteral(
"distance_unit" ) ) )
1190 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
1194 if ( props.contains( QStringLiteral(
"distance_map_unit_scale" ) ) )
1198 if ( props.contains( QStringLiteral(
"ignore_rings" ) ) )
1200 sl->setIgnoreRings( props[QStringLiteral(
"ignore_rings" )].toInt() );
1204 sl->setColorRamp( gradientRamp );
1207 sl->restoreOldDataDefinedProperties( props );
1209 return sl.release();
1214 return QStringLiteral(
"ShapeburstFill" );
1219 if ( mGradientRamp.get() == ramp )
1222 mGradientRamp.reset( ramp );
1225void QgsShapeburstFillSymbolLayer::applyDataDefinedSymbology(
QgsSymbolRenderContext &context, QColor &color, QColor &color2,
int &blurRadius,
bool &useWholeShape,
1226 double &maxDistance,
bool &ignoreRings )
1283 selColor.setAlphaF( context.
opacity() );
1284 mSelBrush = QBrush( selColor );
1303 p->setBrush( mSelBrush );
1304 QPointF
offset = mOffset;
1339 int outputPixelMaxDist = 0;
1347 std::unique_ptr< QgsGradientColorRamp > twoColorGradientRamp;
1350 twoColorGradientRamp = std::make_unique< QgsGradientColorRamp >( color1,
color2 );
1354 p->setPen( QPen( Qt::NoPen ) );
1359 int pointsWidth =
static_cast< int >( std::round( points.boundingRect().width() ) );
1360 int pointsHeight =
static_cast< int >( std::round( points.boundingRect().height() ) );
1361 int imWidth = pointsWidth + ( sideBuffer * 2 );
1362 int imHeight = pointsHeight + ( sideBuffer * 2 );
1368 std::unique_ptr< QImage > fillImage = std::make_unique< QImage >( imWidth,
1369 imHeight, QImage::Format_ARGB32_Premultiplied );
1370 if ( fillImage->isNull() )
1380 std::unique_ptr< QImage > alphaImage = std::make_unique< QImage >( fillImage->width(), fillImage->height(), QImage::Format_ARGB32_Premultiplied );
1381 if ( alphaImage->isNull() )
1393 fillImage->fill( Qt::black );
1399 alphaImage->fill( Qt::transparent );
1405 QPainter imgPainter;
1406 imgPainter.begin( alphaImage.get() );
1407 imgPainter.setRenderHint( QPainter::Antialiasing,
true );
1408 imgPainter.setBrush( QBrush( Qt::white ) );
1409 imgPainter.setPen( QPen( Qt::black ) );
1410 imgPainter.translate( -points.boundingRect().left() + sideBuffer, - points.boundingRect().top() + sideBuffer );
1419 imgPainter.begin( fillImage.get() );
1422 imgPainter.drawImage( 0, 0, *alphaImage );
1429 imgPainter.setBrush( QBrush( Qt::white ) );
1430 imgPainter.setPen( QPen( Qt::black ) );
1431 imgPainter.translate( -points.boundingRect().left() + sideBuffer, - points.boundingRect().top() + sideBuffer );
1440 double *dtArray = distanceTransform( fillImage.get(), context.
renderContext() );
1460 imgPainter.begin( fillImage.get() );
1461 imgPainter.setCompositionMode( QPainter::CompositionMode_DestinationIn );
1462 imgPainter.drawImage( 0, 0, *alphaImage );
1470 QPointF
offset = mOffset;
1487 p->drawImage( points.boundingRect().left() - sideBuffer, points.boundingRect().top() - sideBuffer, *fillImage );
1498void QgsShapeburstFillSymbolLayer::distanceTransform1d(
double *f,
int n,
int *v,
double *z,
double *d )
1504 for (
int q = 1; q <= n - 1; q++ )
1506 double s = ( ( f[q] +
static_cast< double >( q ) * q ) - ( f[v[k]] + (
static_cast< double >( v[k] ) * v[k] ) ) ) / ( 2 * q - 2 * v[k] );
1510 s = ( ( f[q] +
static_cast< double >( q ) * q ) - ( f[v[k]] + (
static_cast< double >( v[k] ) * v[k] ) ) ) / ( 2 * q - 2 * v[k] );
1519 for (
int q = 0; q <= n - 1; q++ )
1521 while ( z[k + 1] < q )
1523 d[q] =
static_cast< double >( q - v[k] ) * ( q - v[k] ) + f[v[k]];
1528void QgsShapeburstFillSymbolLayer::distanceTransform2d(
double *im,
int width,
int height,
QgsRenderContext &context )
1530 int maxDimension = std::max( width, height );
1531 double *f =
new double[ maxDimension ];
1532 int *v =
new int[ maxDimension ];
1533 double *z =
new double[ maxDimension + 1 ];
1534 double *d =
new double[ maxDimension ];
1537 for (
int x = 0; x < width; x++ )
1542 for (
int y = 0; y < height; y++ )
1544 f[y] = im[ x +
static_cast< std::size_t
>( y ) * width ];
1546 distanceTransform1d( f, height, v, z, d );
1547 for (
int y = 0; y < height; y++ )
1549 im[ x +
static_cast< std::size_t
>( y ) * width ] = d[y];
1554 for (
int y = 0; y < height; y++ )
1559 for (
int x = 0; x < width; x++ )
1561 f[x] = im[ x +
static_cast< std::size_t
>( y ) * width ];
1563 distanceTransform1d( f, width, v, z, d );
1564 for (
int x = 0; x < width; x++ )
1566 im[ x +
static_cast< std::size_t
>( y ) * width ] = d[x];
1577double *QgsShapeburstFillSymbolLayer::distanceTransform( QImage *im,
QgsRenderContext &context )
1579 int width = im->width();
1580 int height = im->height();
1582 double *dtArray =
new double[
static_cast< std::size_t
>( width ) * height];
1586 std::size_t idx = 0;
1587 for (
int heightIndex = 0; heightIndex < height; ++heightIndex )
1592 const QRgb *scanLine =
reinterpret_cast< const QRgb *
>( im->constScanLine( heightIndex ) );
1593 for (
int widthIndex = 0; widthIndex < width; ++widthIndex )
1595 tmpRgb = scanLine[widthIndex];
1596 if ( qRed( tmpRgb ) == 0 )
1604 dtArray[ idx ] =
INF;
1611 distanceTransform2d( dtArray, width, height, context );
1616void QgsShapeburstFillSymbolLayer::dtArrayToQImage(
double *array, QImage *im,
QgsColorRamp *ramp,
QgsRenderContext &context,
bool useWholeShape,
int maxPixelDistance )
1618 int width = im->width();
1619 int height = im->height();
1622 double maxDistanceValue;
1627 double dtMaxValue = array[0];
1628 for ( std::size_t i = 1; i < static_cast< std::size_t >( width ) * height; ++i )
1630 if ( array[i] > dtMaxValue )
1632 dtMaxValue = array[i];
1637 maxDistanceValue = std::sqrt( dtMaxValue );
1642 maxDistanceValue = maxPixelDistance;
1646 std::size_t idx = 0;
1647 double squaredVal = 0;
1650 for (
int heightIndex = 0; heightIndex < height; ++heightIndex )
1655 QRgb *scanLine =
reinterpret_cast< QRgb *
>( im->scanLine( heightIndex ) );
1656 for (
int widthIndex = 0; widthIndex < width; ++widthIndex )
1659 squaredVal = array[idx];
1662 if ( maxDistanceValue > 0 )
1664 pixVal = squaredVal > 0 ? std::min( ( std::sqrt( squaredVal ) / maxDistanceValue ), 1.0 ) : 0;
1673 scanLine[widthIndex] = qPremultiply( ramp->
color( pixVal ).rgba() );
1684 map[QStringLiteral(
"color_type" )] = QString::number(
static_cast< int >( mColorType ) );
1685 map[QStringLiteral(
"blur_radius" )] = QString::number( mBlurRadius );
1686 map[QStringLiteral(
"use_whole_shape" )] = QString::number( mUseWholeShape );
1687 map[QStringLiteral(
"max_distance" )] = QString::number( mMaxDistance );
1690 map[QStringLiteral(
"ignore_rings" )] = QString::number( mIgnoreRings );
1694 if ( mGradientRamp )
1696#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
1697 map.unite( mGradientRamp->properties() );
1699 map.insert( mGradientRamp->properties() );
1708 std::unique_ptr< QgsShapeburstFillSymbolLayer > sl = std::make_unique< QgsShapeburstFillSymbolLayer >(
mColor, mColor2, mColorType, mBlurRadius, mUseWholeShape, mMaxDistance );
1709 if ( mGradientRamp )
1711 sl->setColorRamp( mGradientRamp->clone() );
1713 sl->setDistanceUnit( mDistanceUnit );
1714 sl->setDistanceMapUnitScale( mDistanceMapUnitScale );
1715 sl->setIgnoreRings( mIgnoreRings );
1716 sl->setOffset( mOffset );
1717 sl->setOffsetUnit( mOffsetUnit );
1718 sl->setOffsetMapUnitScale( mOffsetMapUnitScale );
1721 return sl.release();
1726 double offsetBleed = context.
convertToPainterUnits( std::max( std::fabs( mOffset.x() ), std::fabs( mOffset.y() ) ), mOffsetUnit, mOffsetMapUnitScale );
1737 mDistanceUnit = unit;
1743 if ( mDistanceUnit == mOffsetUnit )
1745 return mDistanceUnit;
1747 return Qgis::RenderUnit::Unknown;
1752 return mDistanceUnit == Qgis::RenderUnit::MapUnits || mDistanceUnit == Qgis::RenderUnit::MetersInMapUnits
1753 || mOffsetUnit == Qgis::RenderUnit::MapUnits || mOffsetUnit == Qgis::RenderUnit::MetersInMapUnits;
1758 mDistanceMapUnitScale = scale;
1759 mOffsetMapUnitScale = scale;
1764 if ( mDistanceMapUnitScale == mOffsetMapUnitScale )
1766 return mDistanceMapUnitScale;
1791 p->setPen( QPen( Qt::NoPen ) );
1793 QTransform bkTransform =
mBrush.transform();
1797 QTransform t =
mBrush.transform();
1798 t.translate( leftCorner.x(), leftCorner.y() );
1799 mBrush.setTransform( t );
1803 QTransform t =
mBrush.transform();
1804 t.translate( 0, 0 );
1805 mBrush.setTransform( t );
1811 p->setBrush( QBrush( selColor ) );
1817 QTransform t =
mBrush.transform();
1819 mBrush.setTransform( t );
1824 mBrush.setTransform( bkTransform );
1860 return Qt::SolidLine;
1864 return Qt::SolidLine;
1868 return mStroke->dxfPenStyle();
1904 , mPatternWidth( width )
1908 mColor = QColor( 255, 255, 255 );
1914 , mPatternWidth( width )
1915 , mSvgData( svgData )
1920 mColor = QColor( 255, 255, 255 );
1921 setDefaultSvgParams();
1929 mPatternWidthUnit = unit;
1930 mSvgStrokeWidthUnit = unit;
1933 mStroke->setOutputUnit( unit );
1939 if ( mPatternWidthUnit != unit || mSvgStrokeWidthUnit != unit ||
mStrokeWidthUnit != unit )
1941 return Qgis::RenderUnit::Unknown;
1949 mPatternWidthMapUnitScale = scale;
1950 mSvgStrokeWidthMapUnitScale = scale;
1956 mPatternWidthMapUnitScale == mSvgStrokeWidthMapUnitScale &&
1959 return mPatternWidthMapUnitScale;
1969 mSvgFilePath = svgPath;
1970 setDefaultSvgParams();
1980 if (
properties.contains( QStringLiteral(
"width" ) ) )
1982 width =
properties[QStringLiteral(
"width" )].toDouble();
1984 if (
properties.contains( QStringLiteral(
"svgFile" ) ) )
1988 if (
properties.contains( QStringLiteral(
"angle" ) ) )
1993 std::unique_ptr< QgsSVGFillSymbolLayer > symbolLayer;
1996 symbolLayer = std::make_unique< QgsSVGFillSymbolLayer >(
svgFilePath, width,
angle );
2000 if (
properties.contains( QStringLiteral(
"data" ) ) )
2002 data = QByteArray::fromHex(
properties[QStringLiteral(
"data" )].toString().toLocal8Bit() );
2004 symbolLayer = std::make_unique< QgsSVGFillSymbolLayer >( data, width,
angle );
2008 if (
properties.contains( QStringLiteral(
"svgFillColor" ) ) )
2013 else if (
properties.contains( QStringLiteral(
"color" ) ) )
2017 if (
properties.contains( QStringLiteral(
"svgOutlineColor" ) ) )
2022 else if (
properties.contains( QStringLiteral(
"outline_color" ) ) )
2026 else if (
properties.contains( QStringLiteral(
"line_color" ) ) )
2030 if (
properties.contains( QStringLiteral(
"svgOutlineWidth" ) ) )
2033 symbolLayer->setSvgStrokeWidth(
properties[QStringLiteral(
"svgOutlineWidth" )].toDouble() );
2035 else if (
properties.contains( QStringLiteral(
"outline_width" ) ) )
2037 symbolLayer->setSvgStrokeWidth(
properties[QStringLiteral(
"outline_width" )].toDouble() );
2039 else if (
properties.contains( QStringLiteral(
"line_width" ) ) )
2041 symbolLayer->setSvgStrokeWidth(
properties[QStringLiteral(
"line_width" )].toDouble() );
2045 if (
properties.contains( QStringLiteral(
"pattern_width_unit" ) ) )
2049 if (
properties.contains( QStringLiteral(
"pattern_width_map_unit_scale" ) ) )
2053 if (
properties.contains( QStringLiteral(
"svg_outline_width_unit" ) ) )
2057 if (
properties.contains( QStringLiteral(
"svg_outline_width_map_unit_scale" ) ) )
2061 if (
properties.contains( QStringLiteral(
"outline_width_unit" ) ) )
2065 if (
properties.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
2070 if (
properties.contains( QStringLiteral(
"parameters" ) ) )
2076 symbolLayer->restoreOldDataDefinedProperties(
properties );
2078 return symbolLayer.release();
2083 QVariantMap::iterator it =
properties.find( QStringLiteral(
"svgFile" ) );
2095 return QStringLiteral(
"SVGFill" );
2098void QgsSVGFillSymbolLayer::applyPattern( QBrush &brush,
const QString &svgFilePath,
double patternWidth,
Qgis::RenderUnit patternWidthUnit,
2099 const QColor &svgFillColor,
const QColor &svgStrokeColor,
double svgStrokeWidth,
2103 if ( mSvgViewBox.isNull() )
2110 if (
static_cast< int >( size ) < 1.0 || 10000.0 < size )
2112 brush.setTextureImage( QImage() );
2116 bool fitsInCache =
true;
2124 double hwRatio = 1.0;
2125 if ( patternPict.width() > 0 )
2127 hwRatio =
static_cast< double >( patternPict.height() ) /
static_cast< double >( patternPict.width() );
2129 patternImage = QImage(
static_cast< int >( size ),
static_cast< int >( size * hwRatio ), QImage::Format_ARGB32_Premultiplied );
2130 patternImage.fill( 0 );
2132 QPainter p( &patternImage );
2133 p.drawPicture( QPointF( size / 2, size * hwRatio / 2 ), patternPict );
2136 QTransform brushTransform;
2139 QImage transparentImage = patternImage.copy();
2141 brush.setTextureImage( transparentImage );
2145 brush.setTextureImage( patternImage );
2147 brush.setTransform( brushTransform );
2155 applyPattern(
mBrush, mSvgFilePath, mPatternWidth, mPatternWidthUnit,
mColor, mSvgStrokeColor, mSvgStrokeWidth, mSvgStrokeWidthUnit, context, mPatternWidthMapUnitScale, mSvgStrokeWidthMapUnitScale, evaluatedParameters );
2180 for (
auto ringIt = rings->constBegin(); ringIt != rings->constEnd(); ++ringIt )
2191 if ( !mSvgFilePath.isEmpty() )
2193 map.insert( QStringLiteral(
"svgFile" ), mSvgFilePath );
2197 map.insert( QStringLiteral(
"data" ), QString( mSvgData.toHex() ) );
2200 map.insert( QStringLiteral(
"width" ), QString::number( mPatternWidth ) );
2201 map.insert( QStringLiteral(
"angle" ), QString::number(
mAngle ) );
2206 map.insert( QStringLiteral(
"outline_width" ), QString::number( mSvgStrokeWidth ) );
2223 std::unique_ptr< QgsSVGFillSymbolLayer > clonedLayer;
2224 if ( !mSvgFilePath.isEmpty() )
2226 clonedLayer = std::make_unique< QgsSVGFillSymbolLayer >( mSvgFilePath, mPatternWidth,
mAngle );
2227 clonedLayer->setSvgFillColor(
mColor );
2228 clonedLayer->setSvgStrokeColor( mSvgStrokeColor );
2229 clonedLayer->setSvgStrokeWidth( mSvgStrokeWidth );
2233 clonedLayer = std::make_unique< QgsSVGFillSymbolLayer >( mSvgData, mPatternWidth,
mAngle );
2236 clonedLayer->setPatternWidthUnit( mPatternWidthUnit );
2237 clonedLayer->setPatternWidthMapUnitScale( mPatternWidthMapUnitScale );
2238 clonedLayer->setSvgStrokeWidthUnit( mSvgStrokeWidthUnit );
2239 clonedLayer->setSvgStrokeWidthMapUnitScale( mSvgStrokeWidthMapUnitScale );
2243 clonedLayer->setParameters( mParameters );
2247 clonedLayer->setSubSymbol( mStroke->clone() );
2251 return clonedLayer.release();
2256 QDomElement symbolizerElem = doc.createElement( QStringLiteral(
"se:PolygonSymbolizer" ) );
2257 if ( !props.value( QStringLiteral(
"uom" ), QString() ).toString().isEmpty() )
2258 symbolizerElem.setAttribute( QStringLiteral(
"uom" ), props.value( QStringLiteral(
"uom" ), QString() ).toString() );
2259 element.appendChild( symbolizerElem );
2263 QDomElement fillElem = doc.createElement( QStringLiteral(
"se:Fill" ) );
2264 symbolizerElem.appendChild( fillElem );
2266 QDomElement graphicFillElem = doc.createElement( QStringLiteral(
"se:GraphicFill" ) );
2267 fillElem.appendChild( graphicFillElem );
2269 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
2270 graphicFillElem.appendChild( graphicElem );
2272 if ( !mSvgFilePath.isEmpty() )
2283 symbolizerElem.appendChild( doc.createComment( QStringLiteral(
"SVG from data not implemented yet" ) ) );
2289 double angle = props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toDouble( &ok );
2292 angleFunc = QStringLiteral(
"%1 + %2" ).arg( props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toString() ).arg(
mAngle );
2305 mStroke->toSld( doc, element, props );
2311 return mPatternWidthUnit == Qgis::RenderUnit::MapUnits || mPatternWidthUnit == Qgis::RenderUnit::MetersInMapUnits
2312 || mSvgStrokeWidthUnit == Qgis::RenderUnit::MapUnits || mSvgStrokeWidthUnit == Qgis::RenderUnit::MetersInMapUnits;
2317 return mStroke.get();
2324 mStroke.reset(
nullptr );
2337 mStroke.reset( lineSymbol );
2347 if ( mStroke && mStroke->symbolLayer( 0 ) )
2349 double subLayerBleed = mStroke->symbolLayer( 0 )->estimateMaxBleed( context );
2350 return subLayerBleed;
2360 return QColor( Qt::black );
2362 return mStroke->color();
2369 attr.unite( mStroke->usedAttributes( context ) );
2377 if ( mStroke && mStroke->hasDataDefinedProperties() )
2384 QString path, mimeType;
2386 Qt::PenStyle penStyle;
2387 double size, strokeWidth;
2389 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
2390 if ( fillElem.isNull() )
2393 QDomElement graphicFillElem = fillElem.firstChildElement( QStringLiteral(
"GraphicFill" ) );
2394 if ( graphicFillElem.isNull() )
2397 QDomElement graphicElem = graphicFillElem.firstChildElement( QStringLiteral(
"Graphic" ) );
2398 if ( graphicElem.isNull() )
2404 if ( mimeType != QLatin1String(
"image/svg+xml" ) )
2409 double scaleFactor = 1.0;
2410 const QString uom = element.attribute( QStringLiteral(
"uom" ) );
2412 size = size * scaleFactor;
2413 strokeWidth = strokeWidth * scaleFactor;
2420 double d = angleFunc.toDouble( &ok );
2425 std::unique_ptr< QgsSVGFillSymbolLayer > sl = std::make_unique< QgsSVGFillSymbolLayer >( path, size,
angle );
2426 sl->setOutputUnit( sldUnitSize );
2429 sl->setSvgStrokeWidth( strokeWidth );
2432 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
2433 if ( !strokeElem.isNull() )
2444 return sl.release();
2462 double width = mPatternWidth;
2468 QString svgFile = mSvgFilePath;
2487 double strokeWidth = mSvgStrokeWidth;
2496 mSvgStrokeWidthUnit, context, mPatternWidthMapUnitScale, mSvgStrokeWidthMapUnitScale, evaluatedParameters );
2500void QgsSVGFillSymbolLayer::storeViewBox()
2502 if ( !mSvgData.isEmpty() )
2504 QSvgRenderer r( mSvgData );
2507 mSvgViewBox = r.viewBoxF();
2512 mSvgViewBox = QRectF();
2515void QgsSVGFillSymbolLayer::setDefaultSvgParams()
2517 if ( mSvgFilePath.isEmpty() )
2522 bool hasFillParam, hasFillOpacityParam, hasStrokeParam, hasStrokeWidthParam, hasStrokeOpacityParam;
2523 bool hasDefaultFillColor, hasDefaultFillOpacity, hasDefaultStrokeColor, hasDefaultStrokeWidth, hasDefaultStrokeOpacity;
2524 QColor defaultFillColor, defaultStrokeColor;
2525 double defaultStrokeWidth, defaultFillOpacity, defaultStrokeOpacity;
2527 hasFillOpacityParam, hasDefaultFillOpacity, defaultFillOpacity,
2528 hasStrokeParam, hasDefaultStrokeColor, defaultStrokeColor,
2529 hasStrokeWidthParam, hasDefaultStrokeWidth, defaultStrokeWidth,
2530 hasStrokeOpacityParam, hasDefaultStrokeOpacity, defaultStrokeOpacity );
2532 double newFillOpacity = hasFillOpacityParam ?
mColor.alphaF() : 1.0;
2533 double newStrokeOpacity = hasStrokeOpacityParam ? mSvgStrokeColor.alphaF() : 1.0;
2535 if ( hasDefaultFillColor )
2537 mColor = defaultFillColor;
2538 mColor.setAlphaF( newFillOpacity );
2540 if ( hasDefaultFillOpacity )
2542 mColor.setAlphaF( defaultFillOpacity );
2544 if ( hasDefaultStrokeColor )
2546 mSvgStrokeColor = defaultStrokeColor;
2547 mSvgStrokeColor.setAlphaF( newStrokeOpacity );
2549 if ( hasDefaultStrokeOpacity )
2551 mSvgStrokeColor.setAlphaF( defaultStrokeOpacity );
2553 if ( hasDefaultStrokeWidth )
2555 mSvgStrokeWidth = defaultStrokeWidth;
2568 mFillLineSymbol = std::make_unique<QgsLineSymbol>( );
2576 mFillLineSymbol->setWidth( w );
2582 mFillLineSymbol->setColor(
c );
2588 return mFillLineSymbol ? mFillLineSymbol->color() :
mColor;
2600 mFillLineSymbol.reset( qgis::down_cast<QgsLineSymbol *>( symbol ) );
2609 return mFillLineSymbol.get();
2615 if ( mFillLineSymbol )
2616 attr.unite( mFillLineSymbol->usedAttributes( context ) );
2624 if ( mFillLineSymbol && mFillLineSymbol->hasDataDefinedProperties() )
2646 double lineAngleRads { qDegreesToRadians( mLineAngle ) };
2649 QSize size {
static_cast<int>( distancePx ),
static_cast<int>( distancePx ) };
2651 if (
static_cast<int>( mLineAngle ) % 90 != 0 )
2653 size = QSize(
static_cast<int>( distancePx / std::sin( lineAngleRads ) ),
static_cast<int>( distancePx / std::cos( lineAngleRads ) ) );
2656 QPixmap pixmap( size );
2657 pixmap.fill( Qt::transparent );
2659 painter.begin( &pixmap );
2660 painter.setRenderHint( QPainter::Antialiasing );
2666 QgsSymbolRenderContext symbolContext( renderContext, Qgis::RenderUnit::Pixels, 1.0,
false, Qgis::SymbolRenderHints() );
2668 std::unique_ptr< QgsLinePatternFillSymbolLayer > layerClone(
clone() );
2669 layerClone->setOffset( 0 );
2670 layerClone->drawPreviewIcon( symbolContext, pixmap.size() );
2672 return pixmap.toImage();
2684 mDistanceUnit = unit;
2685 mLineWidthUnit = unit;
2688 if ( mFillLineSymbol )
2689 mFillLineSymbol->setOutputUnit( unit );
2695 if ( mDistanceUnit != unit || mLineWidthUnit != unit || ( mOffsetUnit != unit && mOffsetUnit != Qgis::RenderUnit::Percentage ) )
2697 return Qgis::RenderUnit::Unknown;
2704 return mDistanceUnit == Qgis::RenderUnit::MapUnits || mDistanceUnit == Qgis::RenderUnit::MetersInMapUnits
2705 || mLineWidthUnit == Qgis::RenderUnit::MapUnits || mLineWidthUnit == Qgis::RenderUnit::MetersInMapUnits
2706 || mOffsetUnit == Qgis::RenderUnit::MapUnits || mOffsetUnit == Qgis::RenderUnit::MetersInMapUnits;
2712 mDistanceMapUnitScale = scale;
2713 mLineWidthMapUnitScale = scale;
2714 mOffsetMapUnitScale = scale;
2720 mDistanceMapUnitScale == mLineWidthMapUnitScale &&
2721 mLineWidthMapUnitScale == mOffsetMapUnitScale )
2723 return mDistanceMapUnitScale;
2730 std::unique_ptr< QgsLinePatternFillSymbolLayer > patternLayer = std::make_unique< QgsLinePatternFillSymbolLayer >();
2736 QColor
color( Qt::black );
2739 if (
properties.contains( QStringLiteral(
"lineangle" ) ) )
2744 else if (
properties.contains( QStringLiteral(
"angle" ) ) )
2748 patternLayer->setLineAngle(
lineAngle );
2750 if (
properties.contains( QStringLiteral(
"distance" ) ) )
2754 patternLayer->setDistance(
distance );
2756 if (
properties.contains( QStringLiteral(
"linewidth" ) ) )
2761 else if (
properties.contains( QStringLiteral(
"outline_width" ) ) )
2765 else if (
properties.contains( QStringLiteral(
"line_width" ) ) )
2769 patternLayer->setLineWidth(
lineWidth );
2771 if (
properties.contains( QStringLiteral(
"color" ) ) )
2775 else if (
properties.contains( QStringLiteral(
"outline_color" ) ) )
2779 else if (
properties.contains( QStringLiteral(
"line_color" ) ) )
2783 patternLayer->setColor(
color );
2785 if (
properties.contains( QStringLiteral(
"offset" ) ) )
2789 patternLayer->setOffset(
offset );
2792 if (
properties.contains( QStringLiteral(
"distance_unit" ) ) )
2796 if (
properties.contains( QStringLiteral(
"distance_map_unit_scale" ) ) )
2800 if (
properties.contains( QStringLiteral(
"line_width_unit" ) ) )
2804 else if (
properties.contains( QStringLiteral(
"outline_width_unit" ) ) )
2808 if (
properties.contains( QStringLiteral(
"line_width_map_unit_scale" ) ) )
2812 if (
properties.contains( QStringLiteral(
"offset_unit" ) ) )
2816 if (
properties.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
2820 if (
properties.contains( QStringLiteral(
"outline_width_unit" ) ) )
2824 if (
properties.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
2828 if (
properties.contains( QStringLiteral(
"coordinate_reference" ) ) )
2832 if (
properties.contains( QStringLiteral(
"clip_mode" ) ) )
2837 patternLayer->restoreOldDataDefinedProperties(
properties );
2839 return patternLayer.release();
2844 return QStringLiteral(
"LinePatternFill" );
2847void QgsLinePatternFillSymbolLayer::applyPattern(
const QgsSymbolRenderContext &context, QBrush &brush,
double lineAngle,
double distance )
2849 mBrush.setTextureImage( QImage() );
2851 if ( !mFillLineSymbol )
2856 std::unique_ptr< QgsLineSymbol > fillLineSymbol( mFillLineSymbol->clone() );
2857 if ( !fillLineSymbol )
2865 double outputPixelOffset = mOffsetUnit == Qgis::RenderUnit::Percentage ? outputPixelDist * mOffset / 100
2873 outputPixelOffset = std::fmod( outputPixelOffset, outputPixelDist );
2874 if ( outputPixelOffset > outputPixelDist / 2.0 )
2875 outputPixelOffset -= outputPixelDist;
2879 double outputPixelBleed = 0;
2880 double outputPixelInterval = 0;
2881 for (
int i = 0; i < fillLineSymbol->symbolLayerCount(); i++ )
2885 outputPixelBleed = std::max( outputPixelBleed, outputPixelLayerBleed );
2888 if ( markerLineLayer )
2897 outputPixelInterval = std::max( outputPixelInterval, outputPixelLayerInterval );
2901 if ( outputPixelInterval > 0 )
2905 double intervalScale = std::round( outputPixelInterval ) / outputPixelInterval;
2906 outputPixelInterval = std::round( outputPixelInterval );
2908 for (
int i = 0; i < fillLineSymbol->symbolLayerCount(); i++ )
2913 if ( markerLineLayer )
2927 height = outputPixelDist;
2928 width = outputPixelInterval > 0 ? outputPixelInterval : height;
2932 width = outputPixelDist;
2933 height = outputPixelInterval > 0 ? outputPixelInterval : width;
2937 height = outputPixelDist / std::cos(
lineAngle * M_PI / 180 );
2938 width = outputPixelDist / std::sin(
lineAngle * M_PI / 180 );
2941 lineAngle = 180 * std::atan2(
static_cast< double >( height ),
static_cast< double >( width ) ) / M_PI;
2947 height = std::abs( height );
2948 width = std::abs( width );
2950 outputPixelDist = std::abs( height * std::cos(
lineAngle * M_PI / 180 ) );
2954 int offsetHeight =
static_cast< int >( std::round( outputPixelOffset / std::cos(
lineAngle * M_PI / 180 ) ) );
2955 outputPixelOffset = offsetHeight * std::cos(
lineAngle * M_PI / 180 );
2964 int bufferMulti =
static_cast< int >( std::max( std::ceil( outputPixelBleed / width ), std::ceil( outputPixelBleed / width ) ) );
2968 bufferMulti = std::max( bufferMulti, 1 );
2970 int xBuffer = width * bufferMulti;
2971 int yBuffer = height * bufferMulti;
2972 int innerWidth = width;
2973 int innerHeight = height;
2974 width += 2 * xBuffer;
2975 height += 2 * yBuffer;
2978 if ( width > 10000 || height > 10000 || width == 0 || height == 0 )
2983 QImage patternImage( width, height, QImage::Format_ARGB32 );
2984 patternImage.fill( 0 );
2986 QPointF p1, p2, p3, p4, p5, p6;
2989 p1 = QPointF( 0, yBuffer );
2990 p2 = QPointF( width, yBuffer );
2991 p3 = QPointF( 0, yBuffer + innerHeight );
2992 p4 = QPointF( width, yBuffer + innerHeight );
2996 p1 = QPointF( xBuffer, height );
2997 p2 = QPointF( xBuffer, 0 );
2998 p3 = QPointF( xBuffer + innerWidth, height );
2999 p4 = QPointF( xBuffer + innerWidth, 0 );
3003 dx = outputPixelDist * std::cos( ( 90 -
lineAngle ) * M_PI / 180.0 );
3004 dy = outputPixelDist * std::sin( ( 90 -
lineAngle ) * M_PI / 180.0 );
3005 p1 = QPointF( 0, height );
3006 p2 = QPointF( width, 0 );
3007 p3 = QPointF( -dx, height - dy );
3008 p4 = QPointF( width - dx, -dy );
3009 p5 = QPointF( dx, height + dy );
3010 p6 = QPointF( width + dx, dy );
3014 dx = outputPixelDist * std::cos( ( 90 -
lineAngle ) * M_PI / 180.0 );
3015 dy = outputPixelDist * std::sin( ( 90 -
lineAngle ) * M_PI / 180.0 );
3016 p1 = QPointF( width, 0 );
3017 p2 = QPointF( 0, height );
3018 p3 = QPointF( width - dx, -dy );
3019 p4 = QPointF( -dx, height - dy );
3020 p5 = QPointF( width + dx, dy );
3021 p6 = QPointF( dx, height + dy );
3025 dy = outputPixelDist * std::cos( ( 180 -
lineAngle ) * M_PI / 180 );
3026 dx = outputPixelDist * std::sin( ( 180 -
lineAngle ) * M_PI / 180 );
3027 p1 = QPointF( 0, 0 );
3028 p2 = QPointF( width, height );
3029 p5 = QPointF( dx, -dy );
3030 p6 = QPointF( width + dx, height - dy );
3031 p3 = QPointF( -dx, dy );
3032 p4 = QPointF( width - dx, height + dy );
3036 dy = outputPixelDist * std::cos( ( 180 -
lineAngle ) * M_PI / 180 );
3037 dx = outputPixelDist * std::sin( ( 180 -
lineAngle ) * M_PI / 180 );
3038 p1 = QPointF( width, height );
3039 p2 = QPointF( 0, 0 );
3040 p5 = QPointF( width + dx, height - dy );
3041 p6 = QPointF( dx, -dy );
3042 p3 = QPointF( width - dx, height + dy );
3043 p4 = QPointF( -dx, dy );
3050 p3 = QPointF( tempPt.x(), tempPt.y() );
3052 p4 = QPointF( tempPt.x(), tempPt.y() );
3054 p5 = QPointF( tempPt.x(), tempPt.y() );
3056 p6 = QPointF( tempPt.x(), tempPt.y() );
3060 p1 = QPointF( tempPt.x(), tempPt.y() );
3062 p2 = QPointF( tempPt.x(), tempPt.y() );
3065 QPainter p( &patternImage );
3069 p.setRenderHint( QPainter::Antialiasing,
false );
3070 QPen pen( QColor( Qt::black ) );
3071 pen.setWidthF( 0.1 );
3072 pen.setCapStyle( Qt::FlatCap );
3077 QPolygon polygon = QPolygon() << QPoint( 0, 0 ) << QPoint( width - 1, 0 ) << QPoint( width - 1, height - 1 ) << QPoint( 0, height - 1 ) << QPoint( 0, 0 );
3078 p.drawPolygon( polygon );
3080 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 );
3081 p.drawPolygon( polygon );
3087 p.setRenderHint( QPainter::Antialiasing,
true );
3100 fillLineSymbol->startRender( lineRenderContext, context.
fields() );
3102 QVector<QPolygonF> polygons;
3103 polygons.append( QPolygonF() << p1 << p2 );
3104 polygons.append( QPolygonF() << p3 << p4 );
3107 polygons.append( QPolygonF() << p5 << p6 );
3110 for (
const QPolygonF &polygon : std::as_const( polygons ) )
3112 fillLineSymbol->renderPolyline( polygon, context.
feature(), lineRenderContext, -1, context.
selected() );
3115 fillLineSymbol->stopRender( lineRenderContext );
3119 patternImage = patternImage.copy( xBuffer, yBuffer, patternImage.width() - 2 * xBuffer, patternImage.height() - 2 * yBuffer );
3124 QImage transparentImage = patternImage.copy();
3126 brush.setTextureImage( transparentImage );
3130 brush.setTextureImage( patternImage );
3133 QTransform brushTransform;
3134 brush.setTransform( brushTransform );
3142 || mFillLineSymbol->hasDataDefinedProperties()
3146 if ( mRenderUsingLines )
3148 if ( mFillLineSymbol )
3154 applyPattern( context,
mBrush, mLineAngle, mDistance );
3160 if ( mRenderUsingLines && mFillLineSymbol )
3168 if ( !mRenderUsingLines )
3198 double outputPixelOffset = mOffsetUnit == Qgis::RenderUnit::Percentage ? outputPixelDistance *
offset / 100
3202 outputPixelOffset = std::fmod( outputPixelOffset, outputPixelDistance );
3203 if ( outputPixelOffset > outputPixelDistance / 2.0 )
3204 outputPixelOffset -= outputPixelDistance;
3206 p->setPen( QPen( Qt::NoPen ) );
3211 p->setBrush( QBrush( selColor ) );
3235 std::unique_ptr< QgsPolygon > shapePolygon;
3236 std::unique_ptr< QgsGeometryEngine > shapeEngine;
3244 shapePolygon = std::make_unique< QgsPolygon >();
3248 for (
const QPolygonF &ring : *rings )
3254 shapeEngine->prepareGeometry();
3261 path.addPolygon( points );
3264 for (
const QPolygonF &ring : *rings )
3266 path.addPolygon( ring );
3269 p->setClipPath( path, Qt::IntersectClip );
3275 const QRectF boundingRect = points.boundingRect();
3277 QTransform invertedRotateTransform;
3283 QTransform transform;
3284 if ( applyBrushTransform )
3287 transform.translate( -boundingRect.center().x(),
3288 -boundingRect.center().y() );
3290 transform.translate( boundingRect.center().x(),
3291 boundingRect.center().y() );
3299 const QRectF transformedBounds = transform.map( points ).boundingRect();
3303 left = transformedBounds.left() - buffer * 2;
3304 top = transformedBounds.top() - buffer * 2;
3305 right = transformedBounds.right() + buffer * 2;
3306 bottom = transformedBounds.bottom() + buffer * 2;
3307 invertedRotateTransform = transform.inverted();
3309 if ( !applyBrushTransform )
3311 top -= transformedBounds.top() - ( outputPixelDistance * std::floor( transformedBounds.top() / outputPixelDistance ) );
3316 const bool needsExpressionContext = mFillLineSymbol->hasDataDefinedProperties();
3321 int currentLine = 0;
3322 for (
double currentY = top; currentY <= bottom; currentY += outputPixelDistance )
3327 if ( needsExpressionContext )
3331 double y1 = currentY;
3333 double y2 = currentY;
3334 invertedRotateTransform.map( left, currentY - outputPixelOffset, &x1, &y1 );
3335 invertedRotateTransform.map( right, currentY - outputPixelOffset, &x2, &y2 );
3340 std::unique_ptr< QgsAbstractGeometry > intersection( shapeEngine->intersection( &ls ) );
3341 for (
auto it = intersection->const_parts_begin(); it != intersection->const_parts_end(); ++it )
3343 if (
const QgsLineString *ls = qgsgeometry_cast< const QgsLineString * >( *it ) )
3351 mFillLineSymbol->renderPolyline( QPolygonF() << QPointF( x1, y1 ) << QPointF( x2, y2 ), context.
feature(), context.
renderContext() );
3363 map.insert( QStringLiteral(
"angle" ), QString::number( mLineAngle ) );
3364 map.insert( QStringLiteral(
"distance" ), QString::number( mDistance ) );
3365 map.insert( QStringLiteral(
"line_width" ), QString::number( mLineWidth ) );
3367 map.insert( QStringLiteral(
"offset" ), QString::number( mOffset ) );
3383 if ( mFillLineSymbol )
3394 QDomElement symbolizerElem = doc.createElement( QStringLiteral(
"se:PolygonSymbolizer" ) );
3395 if ( !props.value( QStringLiteral(
"uom" ), QString() ).toString().isEmpty() )
3396 symbolizerElem.setAttribute( QStringLiteral(
"uom" ), props.value( QStringLiteral(
"uom" ), QString() ).toString() );
3397 element.appendChild( symbolizerElem );
3402 QDomElement fillElem = doc.createElement( QStringLiteral(
"se:Fill" ) );
3403 symbolizerElem.appendChild( fillElem );
3405 QDomElement graphicFillElem = doc.createElement( QStringLiteral(
"se:GraphicFill" ) );
3406 fillElem.appendChild( graphicFillElem );
3408 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
3409 graphicFillElem.appendChild( graphicElem );
3414 bool exportOk {
false };
3418 if ( ! image.isNull() )
3420 const QFileInfo info { context.exportFilePath() };
3421 QString pngPath { info.completeSuffix().isEmpty() ? context.exportFilePath() : context.exportFilePath().chopped( info.completeSuffix().length() ).append( QStringLiteral(
"png" ) ) };
3423 image.save( pngPath );
3432 QColor lineColor = mFillLineSymbol ? mFillLineSymbol->color() : QColor();
3433 double lineWidth = mFillLineSymbol ? mFillLineSymbol->width() : 0.0;
3441 double angle = props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toDouble( &ok );
3444 angleFunc = QStringLiteral(
"%1 + %2" ).arg( props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toString() ).arg( mLineAngle );
3448 angleFunc = QString::number(
angle + mLineAngle );
3453 QPointF lineOffset( std::sin( mLineAngle ) * mOffset, std::cos( mLineAngle ) * mOffset );
3461 QString featureStyle;
3462 featureStyle.append(
"Brush(" );
3463 featureStyle.append( QStringLiteral(
"fc:%1" ).arg(
mColor.name() ) );
3464 featureStyle.append( QStringLiteral(
",bc:%1" ).arg( QLatin1String(
"#00000000" ) ) );
3465 featureStyle.append(
",id:\"ogr-brush-2\"" );
3466 featureStyle.append( QStringLiteral(
",a:%1" ).arg( mLineAngle ) );
3467 featureStyle.append( QStringLiteral(
",s:%1" ).arg( mLineWidth * widthScaleFactor ) );
3468 featureStyle.append(
",dx:0mm" );
3469 featureStyle.append( QStringLiteral(
",dy:%1mm" ).arg( mDistance * widthScaleFactor ) );
3470 featureStyle.append(
')' );
3471 return featureStyle;
3477 && ( !mFillLineSymbol || !mFillLineSymbol->hasDataDefinedProperties() ) )
3502 Qt::PenStyle lineStyle;
3504 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
3505 if ( fillElem.isNull() )
3508 QDomElement graphicFillElem = fillElem.firstChildElement( QStringLiteral(
"GraphicFill" ) );
3509 if ( graphicFillElem.isNull() )
3512 QDomElement graphicElem = graphicFillElem.firstChildElement( QStringLiteral(
"Graphic" ) );
3513 if ( graphicElem.isNull() )
3519 if ( name != QLatin1String(
"horline" ) )
3527 double d = angleFunc.toDouble( &ok );
3536 offset = std::sqrt( std::pow( vectOffset.x(), 2 ) + std::pow( vectOffset.y(), 2 ) );
3539 double scaleFactor = 1.0;
3540 const QString uom = element.attribute( QStringLiteral(
"uom" ) );
3542 size = size * scaleFactor;
3545 std::unique_ptr< QgsLinePatternFillSymbolLayer > sl = std::make_unique< QgsLinePatternFillSymbolLayer >();
3546 sl->setOutputUnit( sldUnitSize );
3547 sl->setColor( lineColor );
3549 sl->setLineAngle(
angle );
3551 sl->setDistance( size );
3554 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
3555 if ( !strokeElem.isNull() )
3566 return sl.release();
3618 return Qgis::RenderUnit::Unknown;
3666 std::unique_ptr< QgsPointPatternFillSymbolLayer > layer = std::make_unique< QgsPointPatternFillSymbolLayer >();
3667 if (
properties.contains( QStringLiteral(
"distance_x" ) ) )
3669 layer->setDistanceX(
properties[QStringLiteral(
"distance_x" )].toDouble() );
3671 if (
properties.contains( QStringLiteral(
"distance_y" ) ) )
3673 layer->setDistanceY(
properties[QStringLiteral(
"distance_y" )].toDouble() );
3675 if (
properties.contains( QStringLiteral(
"displacement_x" ) ) )
3677 layer->setDisplacementX(
properties[QStringLiteral(
"displacement_x" )].toDouble() );
3679 if (
properties.contains( QStringLiteral(
"displacement_y" ) ) )
3681 layer->setDisplacementY(
properties[QStringLiteral(
"displacement_y" )].toDouble() );
3683 if (
properties.contains( QStringLiteral(
"offset_x" ) ) )
3685 layer->setOffsetX(
properties[QStringLiteral(
"offset_x" )].toDouble() );
3687 if (
properties.contains( QStringLiteral(
"offset_y" ) ) )
3689 layer->setOffsetY(
properties[QStringLiteral(
"offset_y" )].toDouble() );
3692 if (
properties.contains( QStringLiteral(
"distance_x_unit" ) ) )
3696 if (
properties.contains( QStringLiteral(
"distance_x_map_unit_scale" ) ) )
3700 if (
properties.contains( QStringLiteral(
"distance_y_unit" ) ) )
3704 if (
properties.contains( QStringLiteral(
"distance_y_map_unit_scale" ) ) )
3708 if (
properties.contains( QStringLiteral(
"displacement_x_unit" ) ) )
3712 if (
properties.contains( QStringLiteral(
"displacement_x_map_unit_scale" ) ) )
3716 if (
properties.contains( QStringLiteral(
"displacement_y_unit" ) ) )
3720 if (
properties.contains( QStringLiteral(
"displacement_y_map_unit_scale" ) ) )
3724 if (
properties.contains( QStringLiteral(
"offset_x_unit" ) ) )
3728 if (
properties.contains( QStringLiteral(
"offset_x_map_unit_scale" ) ) )
3732 if (
properties.contains( QStringLiteral(
"offset_y_unit" ) ) )
3736 if (
properties.contains( QStringLiteral(
"offset_y_map_unit_scale" ) ) )
3741 if (
properties.contains( QStringLiteral(
"random_deviation_x" ) ) )
3743 layer->setMaximumRandomDeviationX(
properties[QStringLiteral(
"random_deviation_x" )].toDouble() );
3745 if (
properties.contains( QStringLiteral(
"random_deviation_y" ) ) )
3747 layer->setMaximumRandomDeviationY(
properties[QStringLiteral(
"random_deviation_y" )].toDouble() );
3749 if (
properties.contains( QStringLiteral(
"random_deviation_x_unit" ) ) )
3753 if (
properties.contains( QStringLiteral(
"random_deviation_x_map_unit_scale" ) ) )
3757 if (
properties.contains( QStringLiteral(
"random_deviation_y_unit" ) ) )
3761 if (
properties.contains( QStringLiteral(
"random_deviation_y_map_unit_scale" ) ) )
3765 unsigned long seed = 0;
3766 if (
properties.contains( QStringLiteral(
"seed" ) ) )
3772 std::random_device rd;
3773 std::mt19937 mt(
seed == 0 ? rd() :
seed );
3774 std::uniform_int_distribution<> uniformDist( 1, 999999999 );
3775 seed = uniformDist( mt );
3777 layer->setSeed(
seed );
3779 if (
properties.contains( QStringLiteral(
"outline_width_unit" ) ) )
3783 if (
properties.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
3787 if (
properties.contains( QStringLiteral(
"clip_mode" ) ) )
3791 if (
properties.contains( QStringLiteral(
"coordinate_reference" ) ) )
3796 if (
properties.contains( QStringLiteral(
"angle" ) ) )
3798 layer->setAngle(
properties[QStringLiteral(
"angle" )].toDouble() );
3801 layer->restoreOldDataDefinedProperties(
properties );
3803 return layer.release();
3808 return QStringLiteral(
"PointPatternFill" );
3811void QgsPointPatternFillSymbolLayer::applyPattern(
const QgsSymbolRenderContext &context, QBrush &brush,
double distanceX,
double distanceY,
3812 double displacementX,
double displacementY,
double offsetX,
double offsetY )
3819 double widthOffset = std::fmod(
3822 double heightOffset = std::fmod(
3826 if ( width > 10000 || height > 10000 )
3829 brush.setTextureImage( img );
3833 QImage patternImage( width, height, QImage::Format_ARGB32 );
3834 patternImage.fill( 0 );
3835 if ( patternImage.isNull() )
3837 brush.setTextureImage( QImage() );
3842 QPainter p( &patternImage );
3860 for (
double currentX = -width; currentX <= width * 2.0; currentX += width )
3862 for (
double currentY = -height; currentY <= height * 2.0; currentY += height )
3864 mMarkerSymbol->renderPoint( QPointF( currentX + widthOffset, currentY + heightOffset ), context.
feature(), pointRenderContext );
3875 for (
double currentX = -width; currentX <= width * 2.0; currentX += width )
3877 for (
double currentY = -height / 2.0; currentY <= height * 2.0; currentY += height )
3879 mMarkerSymbol->renderPoint( QPointF( currentX + widthOffset + displacementPixelX, currentY + heightOffset ), context.
feature(), pointRenderContext );
3883 for (
double currentX = -width / 2.0; currentX <= width * 2.0; currentX += width )
3885 for (
double currentY = -height; currentY <= height * 2.0; currentY += height / 2.0 )
3887 mMarkerSymbol->renderPoint( QPointF( currentX + widthOffset + ( std::fmod( currentY, height ) != 0 ? displacementPixelX : 0 ), currentY + heightOffset - displacementPixelY ), context.
feature(), pointRenderContext );
3896 QImage transparentImage = patternImage.copy();
3898 brush.setTextureImage( transparentImage );
3902 brush.setTextureImage( patternImage );
3904 QTransform brushTransform;
3905 brush.setTransform( brushTransform );
3923 if ( mRenderUsingMarkers )
3936 if ( mRenderUsingMarkers )
3962 if ( !mRenderUsingMarkers )
4005 const double widthOffset = std::fmod(
4017 const double heightOffset = std::fmod(
4043 p->setPen( QPen( Qt::NoPen ) );
4048 p->setBrush( QBrush( selColor ) );
4072 std::unique_ptr< QgsPolygon > shapePolygon;
4073 std::unique_ptr< QgsGeometryEngine > shapeEngine;
4080 shapePolygon = std::make_unique< QgsPolygon >();
4084 for (
const QPolygonF &ring : *rings )
4090 shapeEngine->prepareGeometry();
4097 path.addPolygon( points );
4100 for (
const QPolygonF &ring : *rings )
4102 path.addPolygon( ring );
4105 p->setClipPath( path, Qt::IntersectClip );
4111 const QRectF boundingRect = points.boundingRect();
4113 QTransform invertedRotateTransform;
4121 QTransform transform;
4122 if ( applyBrushTransform )
4125 transform.translate( -boundingRect.center().x(),
4126 -boundingRect.center().y() );
4127 transform.rotate( -
angle );
4128 transform.translate( boundingRect.center().x(),
4129 boundingRect.center().y() );
4134 transform.rotate( -
angle );
4137 const QRectF transformedBounds = transform.map( points ).boundingRect();
4138 left = transformedBounds.left() - 2 * width;
4139 top = transformedBounds.top() - 2 * height;
4140 right = transformedBounds.right() + 2 * width;
4141 bottom = transformedBounds.bottom() + 2 * height;
4142 invertedRotateTransform = transform.inverted();
4144 if ( !applyBrushTransform )
4146 left -= transformedBounds.left() - ( width * std::floor( transformedBounds.left() / width ) );
4147 top -= transformedBounds.top() - ( height * std::floor( transformedBounds.top() / height ) );
4152 left = boundingRect.left() - 2 * width;
4153 top = boundingRect.top() - 2 * height;
4154 right = boundingRect.right() + 2 * width;
4155 bottom = boundingRect.bottom() + 2 * height;
4157 if ( !applyBrushTransform )
4159 left -= boundingRect.left() - ( width * std::floor( boundingRect.left() / width ) );
4160 top -= boundingRect.top() - ( height * std::floor( boundingRect.top() / height ) );
4177 const double maxRandomDeviationPixelX =
mRandomDeviationXUnit == Qgis::RenderUnit::Percentage ? ( maxRandomDeviationX * width / 100 )
4186 const double maxRandomDeviationPixelY =
mRandomDeviationYUnit == Qgis::RenderUnit::Percentage ? ( maxRandomDeviationY * height / 100 )
4189 std::random_device rd;
4190 std::mt19937 mt(
seed == 0 ? rd() :
seed );
4191 std::uniform_real_distribution<> uniformDist( 0, 1 );
4197 const bool needsExpressionContext =
mMarkerSymbol->hasDataDefinedProperties();
4205 bool alternateColumn =
false;
4206 int currentCol = -3;
4207 for (
double currentX = left; currentX <= right; currentX += width, alternateColumn = !alternateColumn )
4212 if ( needsExpressionContext )
4215 bool alternateRow =
false;
4216 const double columnX = currentX + widthOffset;
4217 int currentRow = -3;
4218 for (
double currentY = top; currentY <= bottom; currentY += height, alternateRow = !alternateRow )
4223 double y = currentY + heightOffset;
4226 x += displacementPixelX;
4228 if ( !alternateColumn )
4229 y -= displacementPixelY;
4235 invertedRotateTransform.map( xx, yy, &x, &y );
4238 if ( useRandomShift )
4240 x += ( 2 * uniformDist( mt ) - 1 ) * maxRandomDeviationPixelX;
4241 y += ( 2 * uniformDist( mt ) - 1 ) * maxRandomDeviationPixelY;
4244 if ( needsExpressionContext )
4252 bool renderPoint =
true;
4260 renderPoint = shapeEngine->intersects( &p );
4270 renderPoint = shapeEngine->contains( markerBounds.
constGet() );
4272 renderPoint = shapeEngine->intersects( markerBounds.
constGet() );
4298 map.insert( QStringLiteral(
"distance_x" ), QString::number(
mDistanceX ) );
4299 map.insert( QStringLiteral(
"distance_y" ), QString::number(
mDistanceY ) );
4300 map.insert( QStringLiteral(
"displacement_x" ), QString::number(
mDisplacementX ) );
4301 map.insert( QStringLiteral(
"displacement_y" ), QString::number(
mDisplacementY ) );
4302 map.insert( QStringLiteral(
"offset_x" ), QString::number(
mOffsetX ) );
4303 map.insert( QStringLiteral(
"offset_y" ), QString::number(
mOffsetY ) );
4319 map.insert( QStringLiteral(
"random_deviation_x" ), QString::number(
mRandomDeviationX ) );
4320 map.insert( QStringLiteral(
"random_deviation_y" ), QString::number(
mRandomDeviationY ) );
4325 map.insert( QStringLiteral(
"seed" ), QString::number(
mSeed ) );
4326 map.insert( QStringLiteral(
"angle" ),
mAngle );
4345 for (
int symbolLayerIdx = 0; symbolLayerIdx <
mMarkerSymbol->symbolLayerCount(); symbolLayerIdx++ )
4347 QDomElement symbolizerElem = doc.createElement( QStringLiteral(
"se:PolygonSymbolizer" ) );
4348 if ( !props.value( QStringLiteral(
"uom" ), QString() ).toString().isEmpty() )
4349 symbolizerElem.setAttribute( QStringLiteral(
"uom" ), props.value( QStringLiteral(
"uom" ), QString() ).toString() );
4350 element.appendChild( symbolizerElem );
4355 QDomElement fillElem = doc.createElement( QStringLiteral(
"se:Fill" ) );
4356 symbolizerElem.appendChild( fillElem );
4358 QDomElement graphicFillElem = doc.createElement( QStringLiteral(
"se:GraphicFill" ) );
4359 fillElem.appendChild( graphicFillElem );
4366 bool exportOk {
false };
4370 if ( ! image.isNull() )
4372 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
4373 graphicFillElem.appendChild( graphicElem );
4374 const QFileInfo info { context.exportFilePath() };
4375 QString pngPath { info.completeSuffix().isEmpty() ? context.exportFilePath() : context.exportFilePath().chopped( info.completeSuffix().length() ).append( QStringLiteral(
"png" ) ) };
4377 image.save( pngPath );
4396 symbolizerElem.appendChild( graphicMarginElem );
4400 markerLayer->writeSldMarker( doc, graphicFillElem, props );
4404 QString errorMsg = QStringLiteral(
"QgsMarkerSymbolLayer expected, %1 found. Skip it." ).arg( layer->
layerType() );
4405 graphicFillElem.appendChild( doc.createComment( errorMsg ) );
4409 QString errorMsg = QStringLiteral(
"Missing point pattern symbol layer. Skip it." );
4410 graphicFillElem.appendChild( doc.createComment( errorMsg ) );
4419 double angleRads { qDegreesToRadians(
mAngle ) };
4428 if ( displacementXPx != 0 )
4433 if ( displacementYPx != 0 )
4440 QPixmap pixmap( size );
4441 pixmap.fill( Qt::transparent );
4443 painter.begin( &pixmap );
4444 painter.setRenderHint( QPainter::Antialiasing );
4450 QgsSymbolRenderContext symbolContext( renderContext, Qgis::RenderUnit::Pixels, 1.0,
false, Qgis::SymbolRenderHints() );
4452 std::unique_ptr< QgsPointPatternFillSymbolLayer > layerClone(
clone() );
4454 layerClone->setAngle( qRadiansToDegrees( angleRads ) );
4457 layerClone->setMaximumRandomDeviationX( 0 );
4458 layerClone->setMaximumRandomDeviationY( 0 );
4460 layerClone->drawPreviewIcon( symbolContext, pixmap.size() );
4462 return pixmap.toImage();
4470 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
4471 if ( fillElem.isNull() )
4474 QDomElement graphicFillElem = fillElem.firstChildElement( QStringLiteral(
"GraphicFill" ) );
4475 if ( graphicFillElem.isNull() )
4478 QDomElement graphicElem = graphicFillElem.firstChildElement( QStringLiteral(
"Graphic" ) );
4479 if ( graphicElem.isNull() )
4483 if ( !simpleMarkerSl )
4488 layers.append( simpleMarkerSl );
4490 std::unique_ptr< QgsMarkerSymbol > marker = std::make_unique< QgsMarkerSymbol >( layers );
4493 const double markerSize { marker->size() };
4495 std::unique_ptr< QgsPointPatternFillSymbolLayer > pointPatternFillSl = std::make_unique< QgsPointPatternFillSymbolLayer >();
4496 pointPatternFillSl->setSubSymbol( marker.release() );
4498 pointPatternFillSl->setDistanceXUnit( Qgis::RenderUnit::Pixels );
4499 pointPatternFillSl->setDistanceYUnit( Qgis::RenderUnit::Pixels );
4501 auto distanceParser = [ & ](
const QStringList & values )
4503 switch ( values.count( ) )
4508 const double v { values.at( 0 ).toDouble( &ok ) };
4511 pointPatternFillSl->setDistanceX( v * 2 + markerSize );
4512 pointPatternFillSl->setDistanceY( v * 2 + markerSize );
4519 const double vX { values.at( 1 ).toDouble( &ok ) };
4522 pointPatternFillSl->setDistanceX( vX * 2 + markerSize );
4524 const double vY { values.at( 0 ).toDouble( &ok ) };
4527 pointPatternFillSl->setDistanceY( vY * 2 + markerSize );
4534 const double vX { values.at( 1 ).toDouble( &ok ) };
4537 pointPatternFillSl->setDistanceX( vX * 2 + markerSize );
4539 const double vYt { values.at( 0 ).toDouble( &ok ) };
4542 const double vYb { values.at( 2 ).toDouble( &ok ) };
4545 pointPatternFillSl->setDistanceY( ( vYt + vYb ) + markerSize );
4553 const double vYt { values.at( 0 ).toDouble( &ok ) };
4556 const double vYb { values.at( 2 ).toDouble( &ok ) };
4559 pointPatternFillSl->setDistanceY( ( vYt + vYb ) + markerSize );
4562 const double vXr { values.at( 1 ).toDouble( &ok ) };
4565 const double vXl { values.at( 3 ).toDouble( &ok ) };
4568 pointPatternFillSl->setDistanceX( ( vXr + vXl ) + markerSize );
4579 bool distanceFromVendorOption {
false };
4581 for ( QgsStringMap::iterator it = vendorOptions.begin(); it != vendorOptions.end(); ++it )
4584 if ( it.key() == QLatin1String(
"distance" ) )
4586 distanceParser( it.value().split(
',' ) );
4587 distanceFromVendorOption =
true;
4590 else if ( it.key() == QLatin1String(
"graphic-margin" ) )
4592 distanceParser( it.value().split(
' ' ) );
4593 distanceFromVendorOption =
true;
4598 if ( ! distanceFromVendorOption && ! graphicFillElem.elementsByTagName( QStringLiteral(
"Size" ) ).isEmpty() )
4600 const QDomElement sizeElement { graphicFillElem.elementsByTagName( QStringLiteral(
"Size" ) ).at( 0 ).toElement() };
4602 const double size { sizeElement.text().toDouble( &ok ) };
4605 pointPatternFillSl->setDistanceX( size );
4606 pointPatternFillSl->setDistanceY( size );
4610 return pointPatternFillSl.release();
4692 attributes.unite(
mMarkerSymbol->usedAttributes( context ) );
4730 std::unique_ptr< QgsCentroidFillSymbolLayer > sl = std::make_unique< QgsCentroidFillSymbolLayer >();
4732 if (
properties.contains( QStringLiteral(
"point_on_surface" ) ) )
4733 sl->setPointOnSurface(
properties[QStringLiteral(
"point_on_surface" )].toInt() != 0 );
4734 if (
properties.contains( QStringLiteral(
"point_on_all_parts" ) ) )
4735 sl->setPointOnAllParts(
properties[QStringLiteral(
"point_on_all_parts" )].toInt() != 0 );
4736 if (
properties.contains( QStringLiteral(
"clip_points" ) ) )
4737 sl->setClipPoints(
properties[QStringLiteral(
"clip_points" )].toInt() != 0 );
4738 if (
properties.contains( QStringLiteral(
"clip_on_current_part_only" ) ) )
4739 sl->setClipOnCurrentPartOnly(
properties[QStringLiteral(
"clip_on_current_part_only" )].toInt() != 0 );
4741 sl->restoreOldDataDefinedProperties(
properties );
4743 return sl.release();
4748 return QStringLiteral(
"CentroidFill" );
4775 part.exterior = points;
4777 part.rings = *rings;
4784 mCurrentParts << part;
4789 const double prevOpacity =
mMarker->opacity();
4792 mMarker->setOpacity( prevOpacity );
4801 mCurrentParts.clear();
4808 const double prevOpacity =
mMarker->opacity();
4811 render( context, mCurrentParts, feature,
false );
4813 mMarker->setOpacity( prevOpacity );
4818void QgsCentroidFillSymbolLayer::render(
QgsRenderContext &context,
const QVector<QgsCentroidFillSymbolLayer::Part> &parts,
const QgsFeature &feature,
bool selected )
4827 QVector< QgsGeometry > geometryParts;
4828 geometryParts.reserve( parts.size() );
4829 QPainterPath globalPath;
4832 int maxAreaPartIdx = 0;
4834 for (
int i = 0; i < parts.size(); i++ )
4836 const Part part = parts[i];
4839 if ( !geom.
isNull() && !part.rings.empty() )
4841 QgsPolygon *poly = qgsgeometry_cast< QgsPolygon * >( geom.
get() );
4845 int area = poly->
area();
4847 if ( area > maxArea )
4857 globalPath.addPolygon( part.exterior );
4858 for (
const QPolygonF &ring : part.rings )
4860 globalPath.addPolygon( ring );
4865 for (
int i = 0; i < parts.size(); i++ )
4870 const Part part = parts[i];
4878 path.addPolygon( part.exterior );
4879 for (
const QPolygonF &ring : part.rings )
4881 path.addPolygon( ring );
4890 context.
painter()->setClipPath( path );
4910 map[QStringLiteral(
"point_on_surface" )] = QString::number(
mPointOnSurface );
4911 map[QStringLiteral(
"point_on_all_parts" )] = QString::number(
mPointOnAllParts );
4912 map[QStringLiteral(
"clip_points" )] = QString::number(
mClipPoints );
4919 std::unique_ptr< QgsCentroidFillSymbolLayer > x = std::make_unique< QgsCentroidFillSymbolLayer >();
4922 x->setSubSymbol(
mMarker->clone() );
4937 mMarker->toSld( doc, element, props );
4948 std::unique_ptr< QgsMarkerSymbol > marker(
new QgsMarkerSymbol( layers ) );
4950 std::unique_ptr< QgsCentroidFillSymbolLayer > sl = std::make_unique< QgsCentroidFillSymbolLayer >();
4951 sl->setSubSymbol( marker.release() );
4952 sl->setPointOnAllParts(
false );
4953 return sl.release();
4980 attributes.unite(
mMarker->usedAttributes( context ) );
5003 mMarker->setOutputUnit( unit );
5013 return Qgis::RenderUnit::Unknown;
5020 return mMarker->usesMapUnits();
5029 mMarker->setMapUnitScale( scale );
5037 return mMarker->mapUnitScale();
5047 , mImageFilePath( imageFilePath )
5064 if (
properties.contains( QStringLiteral(
"imageFile" ) ) )
5066 imagePath =
properties[QStringLiteral(
"imageFile" )].toString();
5068 if (
properties.contains( QStringLiteral(
"coordinate_mode" ) ) )
5072 if (
properties.contains( QStringLiteral(
"alpha" ) ) )
5074 alpha =
properties[QStringLiteral(
"alpha" )].toDouble();
5076 if (
properties.contains( QStringLiteral(
"offset" ) ) )
5080 if (
properties.contains( QStringLiteral(
"angle" ) ) )
5084 if (
properties.contains( QStringLiteral(
"width" ) ) )
5088 std::unique_ptr< QgsRasterFillSymbolLayer > symbolLayer = std::make_unique< QgsRasterFillSymbolLayer >( imagePath );
5089 symbolLayer->setCoordinateMode( mode );
5090 symbolLayer->setOpacity( alpha );
5091 symbolLayer->setOffset(
offset );
5092 symbolLayer->setAngle(
angle );
5093 symbolLayer->setWidth(
width );
5094 if (
properties.contains( QStringLiteral(
"offset_unit" ) ) )
5098 if (
properties.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
5102 if (
properties.contains( QStringLiteral(
"width_unit" ) ) )
5106 if (
properties.contains( QStringLiteral(
"width_map_unit_scale" ) ) )
5111 symbolLayer->restoreOldDataDefinedProperties(
properties );
5113 return symbolLayer.release();
5118 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
5119 if ( fillElem.isNull() )
5122 QDomElement graphicFillElem = fillElem.firstChildElement( QStringLiteral(
"GraphicFill" ) );
5123 if ( graphicFillElem.isNull() )
5126 QDomElement graphicElem = graphicFillElem.firstChildElement( QStringLiteral(
"Graphic" ) );
5127 if ( graphicElem.isNull() )
5130 QString path, mimeType;
5138 if ( ! QFile::exists( path ) )
5143 std::unique_ptr< QgsRasterFillSymbolLayer> sl = std::make_unique< QgsRasterFillSymbolLayer>( path );
5145 return sl.release();
5150 QVariantMap::iterator it =
properties.find( QStringLiteral(
"imageFile" ) );
5154 it.value() = pathResolver.
writePath( it.value().toString() );
5156 it.value() = pathResolver.
readPath( it.value().toString() );
5168 return QStringLiteral(
"RasterFill" );
5179 QPointF
offset = mOffset;
5197 QRectF boundingRect = points.boundingRect();
5198 mBrush.setTransform(
mBrush.transform().translate( boundingRect.left() -
mBrush.transform().dx(),
5199 boundingRect.top() -
mBrush.transform().dy() ) );
5211 applyPattern(
mBrush, mImageFilePath, mWidth, mOpacity * context.
opacity(), context );
5222 map[QStringLiteral(
"imageFile" )] = mImageFilePath;
5223 map[QStringLiteral(
"coordinate_mode" )] = QString::number(
static_cast< int >( mCoordinateMode ) );
5224 map[QStringLiteral(
"alpha" )] = QString::number( mOpacity );
5228 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
5229 map[QStringLiteral(
"width" )] = QString::number( mWidth );
5237 std::unique_ptr< QgsRasterFillSymbolLayer > sl = std::make_unique< QgsRasterFillSymbolLayer >( mImageFilePath );
5238 sl->setCoordinateMode( mCoordinateMode );
5239 sl->setOpacity( mOpacity );
5240 sl->setOffset( mOffset );
5241 sl->setOffsetUnit( mOffsetUnit );
5242 sl->setOffsetMapUnitScale( mOffsetMapUnitScale );
5244 sl->setWidth( mWidth );
5245 sl->setWidthUnit( mWidthUnit );
5246 sl->setWidthMapUnitScale( mWidthMapUnitScale );
5249 return sl.release();
5254 return context.
convertToPainterUnits( std::max( std::fabs( mOffset.x() ), std::fabs( mOffset.y() ) ), mOffsetUnit, mOffsetMapUnitScale );
5259 return mWidthUnit == Qgis::RenderUnit::MapUnits || mWidthUnit == Qgis::RenderUnit::MetersInMapUnits
5260 || mOffsetUnit == Qgis::RenderUnit::MapUnits || mOffsetUnit == Qgis::RenderUnit::MetersInMapUnits;
5277 mImageFilePath = imagePath;
5282 mCoordinateMode = mode;
5300 if ( !hasWidthExpression && !hasAngleExpression && !hasOpacityExpression && !hasFileExpression )
5306 if ( hasAngleExpression )
5314 if ( !hasWidthExpression && !hasOpacityExpression && !hasFileExpression )
5319 double width = mWidth;
5320 if ( hasWidthExpression )
5326 if ( hasOpacityExpression )
5331 QString file = mImageFilePath;
5332 if ( hasFileExpression )
5345void QgsRasterFillSymbolLayer::applyPattern( QBrush &brush,
const QString &imageFilePath,
const double width,
const double alpha,
const QgsSymbolRenderContext &context )
5350 if ( mWidthUnit != Qgis::RenderUnit::Percentage )
5358 if ( size.isEmpty() )
5361 size.setWidth( (
width * size.width() ) / 100.0 );
5364 if (
static_cast< int >( size.width() ) < 1 || 10000.0 < size.width() )
5368 size.setHeight( 0 );
5376 brush.setTextureImage( img );
5385 : mCountMethod( method )
5386 , mPointCount( pointCount )
5387 , mDensityArea( densityArea )
5398 const int pointCount =
properties.value( QStringLiteral(
"point_count" ), QStringLiteral(
"10" ) ).toInt();
5399 const double densityArea =
properties.value( QStringLiteral(
"density_area" ), QStringLiteral(
"250.0" ) ).toDouble();
5401 unsigned long seed = 0;
5402 if (
properties.contains( QStringLiteral(
"seed" ) ) )
5408 std::random_device rd;
5409 std::mt19937 mt(
seed == 0 ? rd() :
seed );
5410 std::uniform_int_distribution<> uniformDist( 1, 999999999 );
5411 seed = uniformDist( mt );
5416 if (
properties.contains( QStringLiteral(
"density_area_unit" ) ) )
5418 if (
properties.contains( QStringLiteral(
"density_area_unit_scale" ) ) )
5421 if (
properties.contains( QStringLiteral(
"clip_points" ) ) )
5423 sl->setClipPoints(
properties[QStringLiteral(
"clip_points" )].toInt() );
5426 return sl.release();
5431 return QStringLiteral(
"RandomMarkerFill" );
5436 mMarker->setColor(
color );
5442 return mMarker ? mMarker->color() :
mColor;
5458 part.exterior = points;
5460 part.rings = *rings;
5462 if ( mRenderingFeature )
5466 mFeatureSymbolOpacity = context.
opacity();
5467 mCurrentParts << part;
5472 const double prevOpacity = mMarker->opacity();
5473 mMarker->setOpacity( mMarker->opacity() * context.
opacity() );
5475 mMarker->setOpacity( prevOpacity );
5479void QgsRandomMarkerFillSymbolLayer::render(
QgsRenderContext &context,
const QVector<QgsRandomMarkerFillSymbolLayer::Part> &parts,
const QgsFeature &feature,
bool selected )
5488 QVector< QgsGeometry > geometryParts;
5489 geometryParts.reserve( parts.size() );
5492 for (
const Part &part : parts )
5495 if ( !geom.
isNull() && !part.rings.empty() )
5497 QgsPolygon *poly = qgsgeometry_cast< QgsPolygon * >( geom.
get() );
5498 for (
const QPolygonF &ring : part.rings )
5505 geom = geom.
buffer( 0, 0 );
5507 geometryParts << geom;
5511 path.addPolygon( part.exterior );
5512 for (
const QPolygonF &ring : part.rings )
5514 path.addPolygon( ring );
5524 context.
painter()->setClipPath( path );
5528 int count = mPointCount;
5535 switch ( mCountMethod )
5537 case Qgis::PointCountMethod::DensityBased:
5547 count = std::max( 0.0, std::ceil( count * ( geom.
area() /
densityArea ) ) );
5550 case Qgis::PointCountMethod::Absolute:
5554 unsigned long seed = mSeed;
5565 std::sort( randomPoints.begin(), randomPoints.end(), [](
const QgsPointXY & a,
const QgsPointXY & b )->bool
5567 return a.y() < b.y();
5573 const bool needsExpressionContext = mMarker->hasDataDefinedProperties();
5578 for (
const QgsPointXY &p : std::as_const( randomPoints ) )
5580 if ( needsExpressionContext )
5582 mMarker->renderPoint( QPointF( p.x(), p.y() ), feature.
isValid() ? &feature :
nullptr, context, -1, selected );
5596 map.insert( QStringLiteral(
"count_method" ), QString::number(
static_cast< int >( mCountMethod ) ) );
5597 map.insert( QStringLiteral(
"point_count" ), QString::number( mPointCount ) );
5598 map.insert( QStringLiteral(
"density_area" ), QString::number( mDensityArea ) );
5601 map.insert( QStringLiteral(
"seed" ), QString::number( mSeed ) );
5602 map.insert( QStringLiteral(
"clip_points" ), QString::number( mClipPoints ) );
5608 std::unique_ptr< QgsRandomMarkerFillSymbolLayer > res = std::make_unique< QgsRandomMarkerFillSymbolLayer >( mPointCount, mCountMethod, mDensityArea, mSeed );
5611 res->setDensityAreaUnit( mDensityAreaUnit );
5612 res->setDensityAreaUnitScale( mDensityAreaUnitScale );
5613 res->mClipPoints = mClipPoints;
5614 res->setSubSymbol( mMarker->clone() );
5617 return res.release();
5627 return mMarker.get();
5639 mColor = mMarker->color();
5648 attributes.unite( mMarker->usedAttributes( context ) );
5657 if ( mMarker && mMarker->hasDataDefinedProperties() )
5694 return mCountMethod;
5699 mCountMethod = method;
5704 return mDensityArea;
5709 mDensityArea = area;
5716 mRenderingFeature =
true;
5717 mCurrentParts.clear();
5722 mRenderingFeature =
false;
5724 const double prevOpacity = mMarker->opacity();
5725 mMarker->setOpacity( mMarker->opacity() * mFeatureSymbolOpacity );
5727 render( context, mCurrentParts, feature,
false );
5729 mFeatureSymbolOpacity = 1;
5730 mMarker->setOpacity( prevOpacity );
5738 mDensityAreaUnit = unit;
5741 mMarker->setOutputUnit( unit );
5749 return mMarker->outputUnit();
5751 return Qgis::RenderUnit::Unknown;
5758 return mMarker->usesMapUnits();
5767 mMarker->setMapUnitScale( scale );
5775 return mMarker->mapUnitScale();
MarkerClipMode
Marker clipping modes.
@ CompletelyWithin
Render complete markers wherever the completely fall within the polygon shape.
@ NoClipping
No clipping, render complete markers.
@ Shape
Clip to polygon shape.
@ CentroidWithin
Render complete markers wherever their centroid falls within the polygon shape.
LineClipMode
Line clipping modes.
@ NoClipping
Lines are not clipped, will extend to shape's bounding box.
@ ClipPainterOnly
Applying clipping on the painter only (i.e. line endpoints will coincide with polygon bounding box,...
@ ClipToIntersection
Clip lines to intersection with polygon shape (slower) (i.e. line endpoints will coincide with polygo...
GradientColorSource
Gradient color sources.
@ ColorRamp
Gradient color ramp.
@ SimpleTwoColor
Simple two color gradient.
GradientSpread
Gradient spread options, which control how gradients are rendered outside of their start and end poin...
@ Reflect
Reflect gradient.
@ Pad
Pad out gradient using colors at endpoint of gradient.
@ Png
Export complex styles to separate PNG files for better compatibility with OGC servers.
PointCountMethod
Methods which define the number of points randomly filling a polygon.
RenderUnit
Rendering size units.
@ RenderingSubSymbol
Set whenever a sub-symbol of a parent symbol is currently being rendered. Can be used during symbol a...
@ RenderSymbolPreview
The render is for a symbol preview only and map based properties may not be available,...
@ RenderMapTile
Draw map such that there are no problems between adjacent tiles.
@ HighQualityImageTransforms
Enable high quality image transformations, which results in better appearance of scaled or rotated ra...
@ RenderBlocking
Render and load remote sources in the same thread to ensure rendering remote sources (svg and images)...
GradientType
Gradient types.
@ Conical
Conical (polar) gradient.
@ Radial
Radial (circular) gradient.
SymbolCoordinateReference
Symbol coordinate reference modes.
@ Feature
Relative to feature/shape being rendered.
@ Viewport
Relative to the whole viewport/output device.
QColor valueAsColor(int key, const QgsExpressionContext &context, const QColor &defaultColor=QColor(), bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a color.
int valueAsInt(int key, const QgsExpressionContext &context, int defaultValue=0, bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as an integer.
bool valueAsBool(int key, const QgsExpressionContext &context, bool defaultValue=false, bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as an boolean.
double valueAsDouble(int key, const QgsExpressionContext &context, double defaultValue=0.0, bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a double.
QString valueAsString(int key, const QgsExpressionContext &context, const QString &defaultString=QString(), bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a string.
static QgsImageCache * imageCache()
Returns the application's image cache, used for caching resampled versions of raster images.
static QgsSvgCache * svgCache()
Returns the application's SVG cache, used for caching SVG images and handling parameter replacement w...
static QgsSymbolLayer * createFromSld(QDomElement &element)
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
QgsSymbol * subSymbol() override
Returns the symbol's sub symbol, if present.
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer's subsymbol. takes ownership of the passed symbol.
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
void setMapUnitScale(const QgsMapUnitScale &scale) override
bool canCauseArtifactsBetweenAdjacentTiles() const override
Returns true if the symbol layer rendering can cause visible artifacts across a single feature when t...
bool pointOnSurface() const
QgsMapUnitScale mapUnitScale() const override
void startFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called before the layer will be rendered for a particular feature.
std::unique_ptr< QgsMarkerSymbol > mMarker
QString layerType() const override
Returns a string that represents this layer type.
void setColor(const QColor &color) override
Sets the "representative" color for the symbol layer.
bool pointOnAllParts() const
Returns whether a point is drawn for all parts or only on the biggest part of multi-part features.
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
bool hasDataDefinedProperties() const override
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
void stopFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called after the layer has been rendered for a particular feature.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
bool clipPoints() const
Returns true if point markers should be clipped to the polygon boundary.
QgsCentroidFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
void toSld(QDomDocument &doc, QDomElement &element, const QVariantMap &props) const override
Saves the symbol layer as SLD.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsCentroidFillSymbolLayer using the specified properties map containing symbol propert...
~QgsCentroidFillSymbolLayer() override
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
double mFeatureSymbolOpacity
QgsCentroidFillSymbolLayer()
QColor color() const override
Returns the "representative" color of the symbol layer.
bool clipOnCurrentPartOnly() const
Returns true if point markers should be clipped to the current part boundary only.
bool mClipOnCurrentPartOnly
Abstract base class for color ramps.
virtual QColor color(double value) const =0
Returns the color corresponding to a specified value.
virtual QVariantMap properties() const =0
Returns a string map containing all the color ramp's properties.
virtual QgsColorRamp * clone() const =0
Creates a clone of the color ramp.
virtual QString type() const =0
Returns a string representing the color ramp type.
static QgsColorRamp * create(const QVariantMap &properties=QVariantMap())
Creates the symbol layer.
static QString typeString()
Returns the string identifier for QgsCptCityColorRamp.
double area() const override SIP_HOLDGIL
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 SIP_HOLDGIL
Tells whether the operation has been canceled already.
static QString uniquePath(const QString &path)
Creates a unique file path name from a desired path by appending "_<n>" (where "<n>" is an integer nu...
void _renderPolygon(QPainter *p, const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context)
Default method to render polygon.
double angle() const
Returns the rotation angle of the fill symbol, in degrees clockwise.
A geometry is the spatial representation of a feature.
QVector< QgsPointXY > randomPointsInPolygon(int count, const std::function< bool(const QgsPointXY &) > &acceptPoint, unsigned long seed=0, QgsFeedback *feedback=nullptr, int maxTriesPerPoint=0) const
Returns a list of count random points generated inside a (multi)polygon geometry (if acceptPoint is s...
const QgsAbstractGeometry * constGet() const SIP_HOLDGIL
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
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.
static QgsGeometry fromRect(const QgsRectangle &rect) SIP_HOLDGIL
Creates a new geometry from a QgsRectangle.
bool isGeosValid(Qgis::GeometryValidityFlags flags=Qgis::GeometryValidityFlags()) const
Checks validity of the geometry using GEOS.
double area() const
Returns the planar, 2-dimensional area of the geometry.
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometry *geometry)
Creates and returns a new geometry engine representing the specified geometry.
QgsGeometry buffer(double distance, int segments) const
Returns a buffer region around this geometry having the given width and with a specified number of se...
static QgsGeometry unaryUnion(const QVector< QgsGeometry > &geometries, const QgsGeometryParameters ¶meters=QgsGeometryParameters())
Compute the unary union on a list of geometries.
Gradient color ramp, which smoothly interpolates between two colors and also supports optional extra ...
static QgsColorRamp * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsColorRamp from a map of properties.
static QString typeString()
Returns the string identifier for QgsGradientColorRamp.
void addStopsToGradient(QGradient *gradient, double opacity=1) const
Copy color ramp stops to a QGradient.
void setColorRamp(QgsColorRamp *ramp)
Sets the color ramp used for the gradient fill.
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
QColor color2() const
Returns the color for endpoint of gradient, only used if the gradient color type is set to SimpleTwoC...
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
bool canCauseArtifactsBetweenAdjacentTiles() const override
Returns true if the symbol layer rendering can cause visible artifacts across a single feature when t...
QgsGradientFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
QgsMapUnitScale mapUnitScale() const override
bool mReferencePoint1IsCentroid
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
Qgis::SymbolCoordinateReference coordinateMode() const
Returns the coordinate mode for gradient, which controls how the gradient stops are positioned.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
Qgis::SymbolCoordinateReference mCoordinateMode
QgsGradientFillSymbolLayer(const QColor &color=DEFAULT_SIMPLEFILL_COLOR, const QColor &color2=Qt::white, Qgis::GradientColorSource gradientColorType=Qgis::GradientColorSource::SimpleTwoColor, Qgis::GradientType gradientType=Qgis::GradientType::Linear, Qgis::SymbolCoordinateReference coordinateMode=Qgis::SymbolCoordinateReference::Feature, Qgis::GradientSpread gradientSpread=Qgis::GradientSpread::Pad)
Constructor for QgsGradientFillSymbolLayer.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsGradientFillSymbolLayer using the specified properties map containing symbol propert...
void setMapUnitScale(const QgsMapUnitScale &scale) override
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
Qgis::GradientSpread mGradientSpread
~QgsGradientFillSymbolLayer() override
Qgis::GradientType mGradientType
QgsColorRamp * mGradientRamp
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QPointF referencePoint1() const
Returns the starting point of gradient fill, in the range [0,0] - [1,1].
Qgis::GradientSpread gradientSpread() const
Returns the gradient spread mode, which controls how the gradient behaves outside of the predefined s...
bool mReferencePoint2IsCentroid
QgsMapUnitScale mOffsetMapUnitScale
Qgis::GradientColorSource gradientColorType() const
Returns the gradient color mode, which controls how gradient color stops are created.
QPointF offset() const
Returns the offset by which polygons will be translated during rendering.
Qgis::GradientColorSource mGradientColorType
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
QString layerType() const override
Returns a string that represents this layer type.
Qgis::RenderUnit mOffsetUnit
Qgis::GradientType gradientType() const
Returns the type of gradient, e.g., linear or radial.
QPointF referencePoint2() const
Returns the end point of gradient fill, in the range [0,0] - [1,1].
QSize originalSize(const QString &path, bool blocking=false) const
Returns the original size (in pixels) of the image at the specified path.
QImage pathAsImage(const QString &path, const QSize size, const bool keepAspectRatio, const double opacity, bool &fitsInCache, bool blocking=false, double targetDpi=96, int frameNumber=-1, bool *isMissing=nullptr)
Returns the specified path rendered as an image.
Base class for polygon renderers generating texture images.
QgsMapUnitScale mStrokeWidthMapUnitScale
QgsImageFillSymbolLayer()
Qgis::SymbolCoordinateReference coordinateReference() const
Returns the coordinate reference mode for fill which controls how the top left corner of the image fi...
double mStrokeWidth
Stroke width.
Qgis::SymbolCoordinateReference mCoordinateReference
double dxfWidth(const QgsDxfExport &e, QgsSymbolRenderContext &context) const override
Gets line width.
QgsMapUnitScale mapUnitScale() const override
Qt::PenStyle dxfPenStyle() const override
Gets pen style.
Qgis::RenderUnit mStrokeWidthUnit
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
void setMapUnitScale(const QgsMapUnitScale &scale) override
virtual void applyDataDefinedSettings(QgsSymbolRenderContext &context)
Applies data defined settings prior to generating the fill symbol brush.
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
~QgsImageFillSymbolLayer() override
virtual bool applyBrushTransformFromContext(QgsSymbolRenderContext *context=nullptr) const
Returns true if the image brush should be transformed using the render context's texture origin.
static void multiplyOpacity(QImage &image, double factor, QgsFeedback *feedback=nullptr)
Multiplies opacity of image pixel values by a factor.
static void stackBlur(QImage &image, int radius, bool alphaOnly=false, QgsFeedback *feedback=nullptr)
Performs a stack blur on an image.
A symbol fill consisting of repeated parallel lines.
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
QgsMapUnitScale mapUnitScale() const override
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
QString layerType() const override
Returns a string that represents this layer type.
QgsLinePatternFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
void stopFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called after the layer has been rendered for a particular feature.
void startFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called before the layer will be rendered for a particular feature.
QColor color() const override
Returns the "representative" color of the symbol layer.
void toSld(QDomDocument &doc, QDomElement &element, const QVariantMap &props) const override
Saves the symbol layer as SLD.
double lineWidth() const
Returns the width of the line subsymbol used to render the parallel lines in the fill.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
void setMapUnitScale(const QgsMapUnitScale &scale) override
Qgis::LineClipMode clipMode() const
Returns the line clipping mode, which defines how lines are clipped at the edges of shapes.
double lineAngle() const
Returns the angle for the parallel lines used to fill the symbol.
void setLineWidth(double w)
Sets the width of the line subsymbol used to render the parallel lines in the fill.
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
void applyDataDefinedSettings(QgsSymbolRenderContext &context) override
Applies data defined settings prior to generating the fill symbol brush.
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer's subsymbol. takes ownership of the passed symbol.
QgsSymbol * subSymbol() override
Returns the symbol's sub symbol, if present.
bool hasDataDefinedProperties() const override
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
void setColor(const QColor &c) override
Sets the "representative" color for the symbol layer.
QImage toTiledPatternImage() const override
Renders the symbol layer as an image that can be used as a seamless pattern fill for polygons,...
double offset() const
Returns the offset distance for lines within the fill, which is the distance to offset the parallel l...
QgsLinePatternFillSymbolLayer()
double distance() const
Returns the distance between lines in the fill pattern.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QString ogrFeatureStyleWidth(double widthScaleFactor) const
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
~QgsLinePatternFillSymbolLayer() override
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
static QgsSymbolLayer * createFromSld(QDomElement &element)
Creates a new QgsLinePatternFillSymbolLayer from a SLD element.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsLinePatternFillSymbolLayer from a properties map.
Line string geometry type, with support for z-dimension and m-values.
QPolygonF asQPolygonF() const override
Returns a QPolygonF representing the points.
static QgsLineString * fromQPolygonF(const QPolygonF &polygon)
Returns a new linestring from a QPolygonF polygon input.
A line symbol type, for rendering LineString and MultiLineString geometries.
Perform transforms between map coordinates and device coordinates.
double mapUnitsPerPixel() const
Returns the current map units per pixel.
Struct for storing maximum and minimum scales for measurements in map units.
Line symbol layer type which draws repeating marker symbols along a line feature.
Abstract base class for marker symbol layers.
A marker symbol type, for rendering Point and MultiPoint geometries.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
Resolves relative paths into absolute paths and vice versa.
QString writePath(const QString &filename) const
Prepare a filename to save it to the project file.
QString readPath(const QString &filename) const
Turn filename read from the project file to an absolute path.
A fill symbol layer which fills polygon shapes with repeating marker symbols.
QgsMapUnitScale mapUnitScale() const override
QgsMapUnitScale mDisplacementYMapUnitScale
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
QgsMapUnitScale mDisplacementXMapUnitScale
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
double distanceX() const
Returns the horizontal distance between rendered markers in the fill.
QgsMapUnitScale mDistanceYMapUnitScale
QImage toTiledPatternImage() const override
Renders the symbol layer as an image that can be used as a seamless pattern fill for polygons,...
double displacementY() const
Returns the vertical displacement for odd numbered columns in the pattern.
void setColor(const QColor &c) override
Sets the "representative" color for the symbol layer.
Qgis::RenderUnit mDistanceXUnit
void startFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called before the layer will be rendered for a particular feature.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsPointPatternFillSymbolLayer using the specified properties map containing symbol pro...
unsigned long seed() const
Returns the random number seed to use when randomly shifting points, or 0 if a truly random sequence ...
Qgis::RenderUnit mDisplacementYUnit
Qgis::MarkerClipMode clipMode() const
Returns the marker clipping mode, which defines how markers are clipped at the edges of shapes.
bool hasDataDefinedProperties() const override
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
double offsetY() const
Returns the vertical offset values for points in the pattern.
QgsSymbol * subSymbol() override
Returns the symbol's sub symbol, if present.
QgsMapUnitScale mDistanceXMapUnitScale
void setMapUnitScale(const QgsMapUnitScale &scale) override
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
QString layerType() const override
Returns a string that represents this layer type.
void applyDataDefinedSettings(QgsSymbolRenderContext &context) override
Applies data defined settings prior to generating the fill symbol brush.
Qgis::RenderUnit mRandomDeviationXUnit
Qgis::RenderUnit mOffsetXUnit
Qgis::RenderUnit mDistanceYUnit
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
QgsMapUnitScale mOffsetXMapUnitScale
void stopFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called after the layer has been rendered for a particular feature.
Qgis::RenderUnit mOffsetYUnit
QColor color() const override
Returns the "representative" color of the symbol layer.
Qgis::RenderUnit mRandomDeviationYUnit
QgsPointPatternFillSymbolLayer()
QgsMapUnitScale mRandomDeviationXMapUnitScale
void toSld(QDomDocument &doc, QDomElement &element, const QVariantMap &props) const override
Saves the symbol layer as SLD.
double offsetX() const
Returns the horizontal offset values for points in the pattern.
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
Qgis::RenderUnit mDisplacementXUnit
std::unique_ptr< QgsMarkerSymbol > mMarkerSymbol
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
QgsPointPatternFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
QgsMapUnitScale mRandomDeviationYMapUnitScale
double displacementX() const
Returns the horizontal displacement for odd numbered rows in the pattern.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
~QgsPointPatternFillSymbolLayer() override
QgsMapUnitScale mOffsetYMapUnitScale
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer's subsymbol. takes ownership of the passed symbol.
double distanceY() const
Returns the vertical distance between rendered markers in the fill.
void setClipMode(Qgis::MarkerClipMode mode)
Sets the marker clipping mode, which defines how markers are clipped at the edges of shapes.
static QgsSymbolLayer * createFromSld(QDomElement &element)
A class to represent a 2D point.
Point geometry type, with support for z-dimension and m-values.
void addInteriorRing(QgsCurve *ring) override
Adds an interior ring to the geometry (takes ownership)
static QgsProject * instance()
Returns the QgsProject singleton instance.
QgsPathResolver pathResolver() const
Returns path resolver object with considering whether the project uses absolute or relative paths and...
QVariant value(int key, const QgsExpressionContext &context, const QVariant &defaultValue=QVariant()) const override
Returns the calculated value of the property with the specified key from within the collection.
bool isActive(int key) const override
Returns true if the collection contains an active property with the specified key.
static QVariantMap propertyMapToVariantMap(const QMap< QString, QgsProperty > &propertyMap)
Convert a map of QgsProperty to a map of QVariant This is useful to save a map of properties.
static QMap< QString, QgsProperty > variantMapToPropertyMap(const QVariantMap &variantMap)
Convert a map of QVariant to a map of QgsProperty This is useful to restore a map of properties.
A fill symbol layer which places markers at random locations within polygons.
~QgsRandomMarkerFillSymbolLayer() override
int pointCount() const
Returns the count of random points to render in the fill.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
void startFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called before the layer will be rendered for a particular feature.
QgsRandomMarkerFillSymbolLayer(int pointCount=10, Qgis::PointCountMethod method=Qgis::PointCountMethod::Absolute, double densityArea=250.0, unsigned long seed=0)
Constructor for QgsRandomMarkerFillSymbolLayer, with the specified pointCount.
unsigned long seed() const
Returns the random number seed to use when generating points, or 0 if a truly random sequence will be...
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsRandomMarkerFillSymbolLayer using the specified properties map containing symbol pro...
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
QString layerType() const override
Returns a string that represents this layer type.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
QgsRandomMarkerFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
void setMapUnitScale(const QgsMapUnitScale &scale) override
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer's subsymbol. takes ownership of the passed symbol.
bool hasDataDefinedProperties() const override
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
void stopFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called after the layer has been rendered for a particular feature.
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
void setCountMethod(Qgis::PointCountMethod method)
Sets the count method used to randomly fill the polygon.
bool clipPoints() const
Returns true if point markers should be clipped to the polygon boundary.
bool canCauseArtifactsBetweenAdjacentTiles() const override
Returns true if the symbol layer rendering can cause visible artifacts across a single feature when t...
void setClipPoints(bool clipped)
Sets whether point markers should be clipped to the polygon boundary.
QgsSymbol * subSymbol() override
Returns the symbol's sub symbol, if present.
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
QColor color() const override
Returns the "representative" color of the symbol layer.
void setSeed(unsigned long seed)
Sets the random number seed to use when generating points, or 0 if a truly random sequence will be us...
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
void setPointCount(int count)
Sets the count of random points to render in the fill.
Qgis::PointCountMethod countMethod() const
Returns the count method used to randomly fill the polygon.
double densityArea() const
Returns the density area used to count the number of points to randomly fill the polygon.
void setColor(const QColor &color) override
Sets the "representative" color for the symbol layer.
void setDensityArea(double area)
Sets the density area used to count the number of points to randomly fill the polygon.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QgsMapUnitScale mapUnitScale() const override
A class for filling symbols with a repeated raster image.
void applyDataDefinedSettings(QgsSymbolRenderContext &context) override
Applies data defined settings prior to generating the fill symbol brush.
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
double width() const
Returns the width used for scaling the image used in the fill.
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
static QgsSymbolLayer * createFromSld(QDomElement &element)
Creates a new QgsRasterFillSymbolLayer from a SLD element.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsRasterFillSymbolLayer from a properties map.
QString layerType() const override
Returns a string that represents this layer type.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QgsRasterFillSymbolLayer(const QString &imageFilePath=QString())
Constructor for QgsRasterFillSymbolLayer, using a raster fill from the specified imageFilePath.
double opacity() const
Returns the opacity for the raster image used in the fill.
~QgsRasterFillSymbolLayer() override
void setOpacity(double opacity)
Sets the opacity for the raster image used in the fill.
QColor color() const override
Returns the "representative" color of the symbol layer.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
QString imageFilePath() const
The path to the raster image used for the fill.
void setImageFilePath(const QString &imagePath)
Sets the path to the raster image used for the fill.
static void resolvePaths(QVariantMap &properties, const QgsPathResolver &pathResolver, bool saving)
Turns relative paths in properties map to absolute when reading and vice versa when writing.
QPointF offset() const
Returns the offset for the fill.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer's subsymbol. takes ownership of the passed symbol.
QgsRasterFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
bool applyBrushTransformFromContext(QgsSymbolRenderContext *context=nullptr) const override
Returns true if the image brush should be transformed using the render context's texture origin.
void setCoordinateMode(Qgis::SymbolCoordinateReference mode)
Set the coordinate mode for fill.
A rectangle specified with double values.
QgsPointXY center() const SIP_HOLDGIL
Returns the center point of the rectangle.
Contains information about the context of a rendering operation.
void setForceVectorOutput(bool force)
Sets whether rendering operations should use vector operations instead of any faster raster shortcuts...
double scaleFactor() const
Returns the scaling factor for the render to convert painter units to physical sizes.
void setScaleFactor(double factor)
Sets the scaling factor for the render to convert painter units to physical sizes.
QSet< QString > disabledSymbolLayersV2() const
When rendering a map layer in a second pass (for selective masking), some symbol layers may be disabl...
double convertToPainterUnits(double size, Qgis::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale(), Qgis::RenderSubcomponentProperty property=Qgis::RenderSubcomponentProperty::Generic) const
Converts a size from the specified units to painter units (pixels).
QPainter * painter()
Returns the destination QPainter for the render operation.
double rendererScale() const
Returns the renderer map scale.
void setPainterFlagsUsingContext(QPainter *painter=nullptr) const
Sets relevant flags on a destination painter, using the flags and settings currently defined for the ...
QgsExpressionContext & expressionContext()
Gets the expression context.
bool forceVectorOutput() const
Returns true if rendering operations should use vector operations instead of any faster raster shortc...
void setDisabledSymbolLayersV2(const QSet< QString > &symbolLayers)
When rendering a map layer in a second pass (for selective masking), some symbol layers may be disabl...
void setFlag(Qgis::RenderContextFlag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected)
const QgsMapToPixel & mapToPixel() const
Returns the context's map to pixel transform, which transforms between map coordinates and device coo...
QColor selectionColor() const
Returns the color to use when rendering selected features.
void setMapToPixel(const QgsMapToPixel &mtp)
Sets the context's map to pixel transform, which transforms between map coordinates and device coordi...
QgsFeedback * feedback() const
Returns the feedback object that can be queried regularly during rendering to check if rendering shou...
QPointF textureOrigin() const
Returns the texture origin, which should be used as a brush transform when rendering using QBrush obj...
void setPainter(QPainter *p)
Sets the destination QPainter for the render operation.
bool renderingStopped() const
Returns true if the rendering operation has been stopped and any ongoing rendering should be canceled...
static QgsRenderContext fromQPainter(QPainter *painter)
Creates a default render context given a pixel based QPainter destination.
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
void setRendererScale(double scale)
Sets the renderer map scale.
Qgis::RenderContextFlags flags() const
Returns combination of flags used for rendering.
const QgsPathResolver & pathResolver() const
Returns the path resolver for conversion between relative and absolute paths during rendering operati...
A class for filling symbols with a repeated SVG file.
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
void setParameters(const QMap< QString, QgsProperty > ¶meters)
Sets the dynamic SVG parameters.
QString svgFilePath() const
Returns the path to the SVG file used to render the fill.
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
QColor dxfColor(QgsSymbolRenderContext &context) const override
Gets color.
static QgsSymbolLayer * createFromSld(QDomElement &element)
Creates a new QgsSVGFillSymbolLayer from a SLD element.
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer's subsymbol. takes ownership of the passed symbol.
QColor svgStrokeColor() const
Returns the stroke color used for rendering the SVG content.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
Qgis::RenderUnit patternWidthUnit() const
Returns the units for the width of the SVG images in the pattern.
const QgsMapUnitScale & svgStrokeWidthMapUnitScale() const
Returns the map unit scale for the pattern's stroke.
double svgStrokeWidth() const
Returns the stroke width used for rendering the SVG content.
QString layerType() const override
Returns a string that represents this layer type.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QMap< QString, QgsProperty > parameters() const
Returns the dynamic SVG parameters.
QgsSVGFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
QgsSVGFillSymbolLayer(const QString &svgFilePath, double width=20, double rotation=0.0)
Constructor for QgsSVGFillSymbolLayer, using the SVG picture at the specified absolute file path.
void setSvgFilePath(const QString &svgPath)
Sets the path to the SVG file to render in the fill.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsSVGFillSymbolLayer from a properties map.
QColor svgFillColor() const
Returns the fill color used for rendering the SVG content.
static void resolvePaths(QVariantMap &properties, const QgsPathResolver &pathResolver, bool saving)
Turns relative paths in properties map to absolute when reading and vice versa when writing.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
const QgsMapUnitScale & patternWidthMapUnitScale() const
Returns the map unit scale for the pattern's width.
Qgis::RenderUnit svgStrokeWidthUnit() const
Returns the units for the stroke width.
double patternWidth() const
Returns the width of the rendered SVG content within the fill (i.e.
bool hasDataDefinedProperties() const override
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
~QgsSVGFillSymbolLayer() override
void setMapUnitScale(const QgsMapUnitScale &scale) override
void toSld(QDomDocument &doc, QDomElement &element, const QVariantMap &props) const override
Saves the symbol layer as SLD.
void applyDataDefinedSettings(QgsSymbolRenderContext &context) override
Applies data defined settings prior to generating the fill symbol brush.
QgsMapUnitScale mapUnitScale() const override
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
QgsSymbol * subSymbol() override
Returns the symbol's sub symbol, if present.
Scoped object for saving and restoring a QPainter object's state.
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
QgsShapeburstFillSymbolLayer(const QColor &color=DEFAULT_SIMPLEFILL_COLOR, const QColor &color2=Qt::white, Qgis::GradientColorSource colorType=Qgis::GradientColorSource::SimpleTwoColor, int blurRadius=0, bool useWholeShape=true, double maxDistance=5)
Constructor for QgsShapeburstFillSymbolLayer.
QgsShapeburstFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
~QgsShapeburstFillSymbolLayer() override
int blurRadius() const
Returns the blur radius, which controls the amount of blurring applied to the fill.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
QColor color2() const
Returns the color used for the endpoint of the shapeburst fill.
void setMapUnitScale(const QgsMapUnitScale &scale) override
QgsMapUnitScale mapUnitScale() const override
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
bool canCauseArtifactsBetweenAdjacentTiles() const override
Returns true if the symbol layer rendering can cause visible artifacts across a single feature when t...
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsShapeburstFillSymbolLayer using the specified properties map containing symbol prope...
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
QPointF offset() const
Returns the offset for the shapeburst fill.
bool useWholeShape() const
Returns whether the shapeburst fill is set to cover the entire shape.
bool ignoreRings() const
Returns whether the shapeburst fill is set to ignore polygon interior rings.
double maxDistance() const
Returns the maximum distance from the shape's boundary which is shaded.
QString layerType() const override
Returns a string that represents this layer type.
Qgis::GradientColorSource colorType() const
Returns the color mode used for the shapeburst fill.
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
void setColorRamp(QgsColorRamp *ramp)
Sets the color ramp used to draw the shapeburst fill.
QgsSimpleFillSymbolLayer(const QColor &color=DEFAULT_SIMPLEFILL_COLOR, Qt::BrushStyle style=DEFAULT_SIMPLEFILL_STYLE, const QColor &strokeColor=DEFAULT_SIMPLEFILL_BORDERCOLOR, Qt::PenStyle strokeStyle=DEFAULT_SIMPLEFILL_BORDERSTYLE, double strokeWidth=DEFAULT_SIMPLEFILL_BORDERWIDTH, Qt::PenJoinStyle penJoinStyle=DEFAULT_SIMPLEFILL_JOINSTYLE)
double dxfWidth(const QgsDxfExport &e, QgsSymbolRenderContext &context) const override
Gets line width.
Qt::PenJoinStyle penJoinStyle() const
QColor strokeColor() const override
Returns the stroke color for the symbol layer.
QColor dxfBrushColor(QgsSymbolRenderContext &context) const override
Gets brush/fill color.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
Qt::BrushStyle dxfBrushStyle() const override
Gets brush/fill style.
QString ogrFeatureStyle(double mmScaleFactor, double mapUnitScaleFactor) const override
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
Qgis::RenderUnit mOffsetUnit
~QgsSimpleFillSymbolLayer() override
void toSld(QDomDocument &doc, QDomElement &element, const QVariantMap &props) const override
Saves the symbol layer as SLD.
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
QColor dxfColor(QgsSymbolRenderContext &context) const override
Gets color.
QColor fillColor() const override
Returns the fill color for the symbol layer.
Qt::PenStyle strokeStyle() const
QString layerType() const override
Returns a string that represents this layer type.
double dxfAngle(QgsSymbolRenderContext &context) const override
Gets angle.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QgsMapUnitScale mOffsetMapUnitScale
double strokeWidth() const
Qgis::RenderUnit mStrokeWidthUnit
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
QPointF offset() const
Returns the offset by which polygons will be translated during rendering.
Qt::PenStyle dxfPenStyle() const override
Gets pen style.
QgsMapUnitScale mStrokeWidthMapUnitScale
QImage toTiledPatternImage() const override
Renders the symbol layer as an image that can be used as a seamless pattern fill for polygons,...
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
QgsSimpleFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
Qt::PenStyle mStrokeStyle
QgsMapUnitScale mapUnitScale() const override
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
Qt::PenJoinStyle mPenJoinStyle
Qt::BrushStyle mBrushStyle
void setMapUnitScale(const QgsMapUnitScale &scale) override
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsSimpleFillSymbolLayer using the specified properties map containing symbol propertie...
static QgsSymbolLayer * createFromSld(QDomElement &element)
The QgsSldExportContext class holds SLD export options and other information related to SLD export of...
QByteArray getImageData(const QString &path, bool blocking=false) const
Gets the SVG content corresponding to the given path.
QPicture svgAsPicture(const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth, double widthScaleFactor, bool forceVectorOutput=false, double fixedAspectRatio=0, bool blocking=false, const QMap< QString, QString > ¶meters=QMap< QString, QString >())
Returns an SVG drawing as a QPicture.
void containsParams(const QString &path, bool &hasFillParam, QColor &defaultFillColor, bool &hasStrokeParam, QColor &defaultStrokeColor, bool &hasStrokeWidthParam, double &defaultStrokeWidth, bool blocking=false) const
Tests if an SVG file contains parameters for fill, stroke color, stroke width.
QImage svgAsImage(const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth, double widthScaleFactor, bool &fitsInCache, double fixedAspectRatio=0, bool blocking=false, const QMap< QString, QString > ¶meters=QMap< QString, QString >())
Returns an SVG drawing as a QImage.
static bool rotationFromSldElement(QDomElement &element, QString &rotationFunc)
static Qgis::MarkerClipMode decodeMarkerClipMode(const QString &string, bool *ok=nullptr)
Decodes a string representing a marker clip mode.
static QString encodePenStyle(Qt::PenStyle style)
static Qt::PenJoinStyle decodePenJoinStyle(const QString &str)
static QString encodeMapUnitScale(const QgsMapUnitScale &mapUnitScale)
static QgsStringMap evaluatePropertiesMap(const QMap< QString, QgsProperty > &propertiesMap, const QgsExpressionContext &context)
Evaluates a map of properties using the given context and returns a variant map with evaluated expres...
static bool displacementFromSldElement(QDomElement &element, QPointF &offset)
static QColor decodeColor(const QString &str)
static QPointF polygonCentroid(const QPolygonF &points)
Calculate the centroid point of a QPolygonF.
static QString encodeBrushStyle(Qt::BrushStyle style)
static QString svgSymbolPathToName(const QString &path, const QgsPathResolver &pathResolver)
Determines an SVG symbol's name from its path.
static void externalGraphicToSld(QDomDocument &doc, QDomElement &element, const QString &path, const QString &mime, const QColor &color, double size=-1)
static QPointF polygonPointOnSurface(const QPolygonF &points, const QVector< QPolygonF > *rings=nullptr)
Calculate a point on the surface of a QPolygonF.
static QPointF toPoint(const QVariant &value, bool *ok=nullptr)
Converts a value to a point.
static void multiplyImageOpacity(QImage *image, qreal opacity)
Multiplies opacity of image pixel values with a (global) transparency value.
static QgsMapUnitScale decodeMapUnitScale(const QString &str)
static double rescaleUom(double size, Qgis::RenderUnit unit, const QVariantMap &props)
Rescales the given size based on the uomScale found in the props, if any is found,...
static QString ogrFeatureStylePen(double width, double mmScaleFactor, double mapUnitsScaleFactor, const QColor &c, Qt::PenJoinStyle joinStyle=Qt::MiterJoin, Qt::PenCapStyle capStyle=Qt::FlatCap, double offset=0.0, const QVector< qreal > *dashPattern=nullptr)
Create ogr feature style string for pen.
static bool externalGraphicFromSld(QDomElement &element, QString &path, QString &mime, QColor &color, double &size)
static void parametricSvgToSld(QDomDocument &doc, QDomElement &graphicElem, const QString &path, const QColor &fillColor, double size, const QColor &strokeColor, double strokeWidth)
Encodes a reference to a parametric SVG into SLD, as a succession of parametric SVG using URL paramet...
static bool lineFromSld(QDomElement &element, Qt::PenStyle &penStyle, QColor &color, double &width, Qt::PenJoinStyle *penJoinStyle=nullptr, Qt::PenCapStyle *penCapStyle=nullptr, QVector< qreal > *customDashPattern=nullptr, double *dashOffset=nullptr)
static QString ogrFeatureStyleBrush(const QColor &fillColr)
Create ogr feature style string for brush.
static QString encodeLineClipMode(Qgis::LineClipMode mode)
Encodes a line clip mode to a string.
static Qgis::LineClipMode decodeLineClipMode(const QString &string, bool *ok=nullptr)
Decodes a string representing a line clip mode.
static QPointF pointOnLineWithDistance(QPointF startPoint, QPointF directionPoint, double distance)
Returns a point on the line from startPoint to directionPoint that is a certain distance away from th...
static QSize tileSize(int width, int height, double &angleRad)
Calculate the minimum size in pixels of a symbol tile given the symbol width and height and the symbo...
static Qt::BrushStyle decodeBrushStyle(const QString &str)
static void lineToSld(QDomDocument &doc, QDomElement &element, Qt::PenStyle penStyle, const QColor &color, double width=-1, const Qt::PenJoinStyle *penJoinStyle=nullptr, const Qt::PenCapStyle *penCapStyle=nullptr, const QVector< qreal > *customDashPattern=nullptr, double dashOffset=0.0)
static QDomElement createVendorOptionElement(QDomDocument &doc, const QString &name, const QString &value)
static bool wellKnownMarkerFromSld(QDomElement &element, QString &name, QColor &color, QColor &strokeColor, Qt::PenStyle &strokeStyle, double &strokeWidth, double &size)
static void createDisplacementElement(QDomDocument &doc, QDomElement &element, QPointF offset)
static QString svgSymbolNameToPath(const QString &name, const QgsPathResolver &pathResolver)
Determines an SVG symbol's path from its name.
static QString encodeColor(const QColor &color)
static bool fillFromSld(QDomElement &element, Qt::BrushStyle &brushStyle, QColor &color)
static void fillToSld(QDomDocument &doc, QDomElement &element, Qt::BrushStyle brushStyle, const QColor &color=QColor())
static Qgis::RenderUnit decodeSldUom(const QString &str, double *scaleFactor=nullptr)
Decodes a SLD unit of measure string to a render unit.
static void createGeometryElement(QDomDocument &doc, QDomElement &element, const QString &geomFunc)
static double estimateMaxSymbolBleed(QgsSymbol *symbol, const QgsRenderContext &context)
Returns the maximum estimated bleed for the symbol.
static void wellKnownMarkerToSld(QDomDocument &doc, QDomElement &element, const QString &name, const QColor &color, const QColor &strokeColor, Qt::PenStyle strokeStyle, double strokeWidth=-1, double size=-1)
static Qt::PenStyle decodePenStyle(const QString &str)
static void createRotationElement(QDomDocument &doc, QDomElement &element, const QString &rotationFunc)
static Qgis::SymbolCoordinateReference decodeCoordinateReference(const QString &string, bool *ok=nullptr)
Decodes a string representing a symbol coordinate reference mode.
static QString encodePoint(QPointF point)
Encodes a QPointF to a string.
static QgsSymbolLayer * createMarkerLayerFromSld(QDomElement &element)
static QString encodePenJoinStyle(Qt::PenJoinStyle style)
static QgsStringMap getVendorOptionList(QDomElement &element)
static QPointF decodePoint(const QString &string)
Decodes a QSizeF from a string.
static QgsSymbolLayer * createLineLayerFromSld(QDomElement &element)
static QString encodeCoordinateReference(Qgis::SymbolCoordinateReference coordinateReference)
Encodes a symbol coordinate reference mode to a string.
static QString encodeMarkerClipMode(Qgis::MarkerClipMode mode)
Encodes a marker clip mode to a string.
@ PropertyGradientReference1X
Gradient reference point 1 x.
@ PropertyShapeburstIgnoreRings
Shapeburst ignore rings.
@ PropertyGradientReference2X
Gradient reference point 2 x.
@ PropertyStrokeStyle
Stroke style (eg solid, dashed)
@ PropertyDistanceX
Horizontal distance between points.
@ PropertyFile
Filename, eg for svg files.
@ PropertyGradientType
Gradient fill type.
@ PropertyAngle
Symbol angle.
@ PropertyLineClipping
Line clipping mode (since QGIS 3.24)
@ PropertyDistanceY
Vertical distance between points.
@ PropertyDisplacementX
Horizontal displacement.
@ PropertyGradientSpread
Gradient spread mode.
@ PropertyOffsetY
Vertical offset.
@ PropertyGradientReference1Y
Gradient reference point 1 y.
@ PropertyLineDistance
Distance between lines, or length of lines for hash line symbols.
@ PropertyBlurRadius
Shapeburst blur radius.
@ PropertyGradientReference2Y
Gradient reference point 2 y.
@ PropertyMarkerClipping
Marker clipping mode (since QGIS 3.24)
@ PropertyDensityArea
Density area.
@ PropertyGradientReference1IsCentroid
Gradient reference point 1 is centroid.
@ PropertyShapeburstUseWholeShape
Shapeburst use whole shape.
@ PropertyOffsetX
Horizontal offset.
@ PropertyJoinStyle
Line join style.
@ PropertyOpacity
Opacity.
@ PropertySecondaryColor
Secondary color (eg for gradient fills)
@ PropertyCoordinateMode
Gradient coordinate mode.
@ PropertyRandomOffsetY
Random offset Y (since QGIS 3.24)
@ PropertyLineAngle
Line angle, or angle of hash lines for hash line symbols.
@ PropertyShapeburstMaxDistance
Shapeburst fill from edge distance.
@ PropertyOffset
Symbol offset.
@ PropertyStrokeWidth
Stroke width.
@ PropertyFillColor
Fill color.
@ PropertyClipPoints
Whether markers should be clipped to polygon boundaries.
@ PropertyPointCount
Point count.
@ PropertyRandomSeed
Random number seed.
@ PropertyRandomOffsetX
Random offset X (since QGIS 3.24)
@ PropertyFillStyle
Fill style (eg solid, dots)
@ PropertyDisplacementY
Vertical displacement.
@ PropertyStrokeColor
Stroke color.
@ PropertyGradientReference2IsCentroid
Gradient reference point 2 is centroid.
@ PropertyWidth
Symbol width.
virtual bool setSubSymbol(QgsSymbol *symbol)
Sets layer's subsymbol. takes ownership of the passed symbol.
Qgis::SymbolType type() const
virtual QColor fillColor() const
Returns the fill color for the symbol layer.
static const bool SELECTION_IS_OPAQUE
Whether styles for selected features ignore symbol alpha.
void removeMasks(QgsRenderContext &context, bool recursive)
When rendering, remove previously installed masks from context painter if recursive is true masks are...
virtual QSet< QString > usedAttributes(const QgsRenderContext &context) const
Returns the set of attributes referenced by the layer.
void copyDataDefinedProperties(QgsSymbolLayer *destLayer) const
Copies all data defined properties of this layer to another symbol layer.
void installMasks(QgsRenderContext &context, bool recursive)
When rendering, install masks on context painter if recursive is true masks are installed recursively...
virtual double estimateMaxBleed(const QgsRenderContext &context) const
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
static const bool SELECT_FILL_BORDER
Whether fill styles for selected features also highlight symbol stroke.
virtual QString layerType() const =0
Returns a string that represents this layer type.
virtual QColor color() const
Returns the "representative" color of the symbol layer.
virtual QColor strokeColor() const
Returns the stroke color for the symbol layer.
void copyPaintEffect(QgsSymbolLayer *destLayer) const
Copies paint effect of this layer to another symbol layer.
QgsPropertyCollection mDataDefinedProperties
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the symbol layer's property collection, used for data defined overrides.
static const bool SELECT_FILL_STYLE
Whether fill styles for selected features uses symbol layer style.
virtual bool hasDataDefinedProperties() const
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
const QgsFeature * feature() const
Returns the current feature being rendered.
QgsFields fields() const
Fields of the layer.
bool selected() const
Returns true if symbols should be rendered using the selected symbol coloring and style.
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for data defined symbology.
qreal opacity() const
Returns the opacity for the symbol.
QgsRenderContext & renderContext()
Returns a reference to the context's render context.
Abstract base class for all rendered symbols.
Qgis::SymbolType type() const
Returns the symbol's type.
double interval() const
Returns the interval between individual symbols.
const QgsMapUnitScale & intervalMapUnitScale() const
Returns the map unit scale for the interval between symbols.
void setInterval(double interval)
Sets the interval between individual symbols.
Qgis::RenderUnit intervalUnit() const
Returns the units for the interval between symbols.
static Q_INVOKABLE Qgis::RenderUnit decodeRenderUnit(const QString &string, bool *ok=nullptr)
Decodes a render unit from a string.
static Q_INVOKABLE QString encodeUnit(Qgis::DistanceUnit unit)
Encodes a distance unit to a string.
static bool isNull(const QVariant &variant)
Returns true if the specified variant should be considered a NULL value.
double ANALYSIS_EXPORT angle(QgsPoint *p1, QgsPoint *p2, QgsPoint *p3, QgsPoint *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
CORE_EXPORT QgsMeshVertex centroid(const QgsMeshFace &face, const QVector< QgsMeshVertex > &vertices)
Returns the centroid of the face.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
QMap< QString, QString > QgsStringMap
#define DEFAULT_SIMPLEFILL_JOINSTYLE
#define DEFAULT_SIMPLEFILL_COLOR
#define DEFAULT_SIMPLEFILL_STYLE
#define DEFAULT_SIMPLEFILL_BORDERSTYLE
#define DEFAULT_SIMPLEFILL_BORDERCOLOR
#define DEFAULT_SIMPLEFILL_BORDERWIDTH
QList< QgsSymbolLayer * > QgsSymbolLayerList
Single variable definition for use within a QgsExpressionContextScope.