44#include <QPagedPaintDevice>
46#include <QSvgRenderer>
47#include <QDomDocument>
54 Qt::PenJoinStyle penJoinStyle )
55 : mBrushStyle( style )
56 , mStrokeColor( strokeColor )
57 , mStrokeStyle( strokeStyle )
58 , mStrokeWidth( strokeWidth )
59 , mPenJoinStyle( penJoinStyle )
103void QgsSimpleFillSymbolLayer::applyDataDefinedSymbology(
QgsSymbolRenderContext &context, QBrush &brush, QPen &pen, QPen &selPen )
128 penColor.setAlphaF( context.
opacity() * penColor.alphaF() );
129 pen.setColor( penColor );
137 double width = exprVal.toDouble( &ok );
141 pen.setWidthF( width );
142 selPen.setWidthF( width );
179 if ( props.contains( QStringLiteral(
"color" ) ) )
181 if ( props.contains( QStringLiteral(
"style" ) ) )
183 if ( props.contains( QStringLiteral(
"color_border" ) ) )
188 else if ( props.contains( QStringLiteral(
"outline_color" ) ) )
192 else if ( props.contains( QStringLiteral(
"line_color" ) ) )
197 if ( props.contains( QStringLiteral(
"style_border" ) ) )
202 else if ( props.contains( QStringLiteral(
"outline_style" ) ) )
206 else if ( props.contains( QStringLiteral(
"line_style" ) ) )
210 if ( props.contains( QStringLiteral(
"width_border" ) ) )
213 strokeWidth = props[QStringLiteral(
"width_border" )].toDouble();
215 else if ( props.contains( QStringLiteral(
"outline_width" ) ) )
217 strokeWidth = props[QStringLiteral(
"outline_width" )].toDouble();
219 else if ( props.contains( QStringLiteral(
"line_width" ) ) )
221 strokeWidth = props[QStringLiteral(
"line_width" )].toDouble();
223 if ( props.contains( QStringLiteral(
"offset" ) ) )
225 if ( props.contains( QStringLiteral(
"joinstyle" ) ) )
230 if ( props.contains( QStringLiteral(
"border_width_unit" ) ) )
234 else if ( props.contains( QStringLiteral(
"outline_width_unit" ) ) )
238 else if ( props.contains( QStringLiteral(
"line_width_unit" ) ) )
242 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
245 if ( props.contains( QStringLiteral(
"border_width_map_unit_scale" ) ) )
247 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
250 sl->restoreOldDataDefinedProperties( props );
258 return QStringLiteral(
"SimpleFill" );
275 selColor.setAlphaF( context.
opacity() );
334 if (
mBrush.style() == Qt::SolidPattern ||
mBrush.style() == Qt::NoBrush || !
dynamic_cast<QPagedPaintDevice *
>( p->device() ) )
346 p->setPen( Qt::NoPen );
350 p->setBrush( Qt::NoBrush );
367 map[QStringLiteral(
"outline_width" )] = QString::number(
mStrokeWidth );
395 QDomElement symbolizerElem = doc.createElement( QStringLiteral(
"se:PolygonSymbolizer" ) );
396 if ( !props.value( QStringLiteral(
"uom" ), QString() ).toString().isEmpty() )
397 symbolizerElem.setAttribute( QStringLiteral(
"uom" ), props.value( QStringLiteral(
"uom" ), QString() ).toString() );
398 element.appendChild( symbolizerElem );
407 bool exportOk {
false };
411 if ( ! image.isNull() )
414 QDomElement fillElem = doc.createElement( QStringLiteral(
"se:Fill" ) );
415 symbolizerElem.appendChild( fillElem );
416 QDomElement graphicFillElem = doc.createElement( QStringLiteral(
"se:GraphicFill" ) );
417 fillElem.appendChild( graphicFillElem );
418 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
419 graphicFillElem.appendChild( graphicElem );
421 const QFileInfo info { context.exportFilePath() };
422 QString pngPath { info.completeSuffix().isEmpty() ? context.exportFilePath() : context.exportFilePath().chopped( info.completeSuffix().length() ).append( QStringLiteral(
"png" ) ) };
424 image.save( pngPath );
439 const double alpha { props.value( QStringLiteral(
"alpha" ), QVariant() ).toDouble( &ok ) };
445 QDomElement fillElem = doc.createElement( QStringLiteral(
"se:Fill" ) );
446 symbolizerElem.appendChild( fillElem );
453 QDomElement strokeElem = doc.createElement( QStringLiteral(
"se:Stroke" ) );
454 symbolizerElem.appendChild( strokeElem );
458 const double alpha { props.value( QStringLiteral(
"alpha" ), QVariant() ).toDouble( &ok ) };
478 symbolStyle.append(
';' );
487 Qt::BrushStyle fillStyle;
491 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
494 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
500 double scaleFactor = 1.0;
501 const QString uom = element.attribute( QStringLiteral(
"uom" ) );
508 sl->setOutputUnit( sldUnitSize );
517 return penBleed + offsetBleed;
575 QPixmap pixmap( QSize( 32, 32 ) );
576 pixmap.fill( Qt::transparent );
578 painter.begin( &pixmap );
579 painter.setRenderHint( QPainter::Antialiasing );
587 std::unique_ptr< QgsSimpleFillSymbolLayer > layerClone(
clone() );
588 layerClone->setStrokeStyle( Qt::PenStyle::NoPen );
589 layerClone->drawPreviewIcon( symbolContext, pixmap.size() );
591 return pixmap.toImage();
599 : mGradientColorType( colorType )
600 , mGradientType( gradientType )
601 , mCoordinateMode( coordinateMode )
602 , mGradientSpread( spread )
603 , mReferencePoint1( QPointF( 0.5, 0 ) )
604 , mReferencePoint2( QPointF( 0.5, 1 ) )
625 bool refPoint1IsCentroid =
false;
627 bool refPoint2IsCentroid =
false;
632 if ( props.contains( QStringLiteral(
"type" ) ) )
634 if ( props.contains( QStringLiteral(
"coordinate_mode" ) ) )
636 if ( props.contains( QStringLiteral(
"spread" ) ) )
638 if ( props.contains( QStringLiteral(
"color_type" ) ) )
640 if ( props.contains( QStringLiteral(
"gradient_color" ) ) )
645 else if ( props.contains( QStringLiteral(
"color" ) ) )
649 if ( props.contains( QStringLiteral(
"gradient_color2" ) ) )
654 if ( props.contains( QStringLiteral(
"reference_point1" ) ) )
656 if ( props.contains( QStringLiteral(
"reference_point1_iscentroid" ) ) )
657 refPoint1IsCentroid = props[QStringLiteral(
"reference_point1_iscentroid" )].toInt();
658 if ( props.contains( QStringLiteral(
"reference_point2" ) ) )
660 if ( props.contains( QStringLiteral(
"reference_point2_iscentroid" ) ) )
661 refPoint2IsCentroid = props[QStringLiteral(
"reference_point2_iscentroid" )].toInt();
662 if ( props.contains( QStringLiteral(
"angle" ) ) )
663 angle = props[QStringLiteral(
"angle" )].toDouble();
665 if ( props.contains( QStringLiteral(
"offset" ) ) )
682 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
684 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
687 sl->setReferencePoint1IsCentroid( refPoint1IsCentroid );
689 sl->setReferencePoint2IsCentroid( refPoint2IsCentroid );
690 sl->setAngle(
angle );
692 sl->setColorRamp( gradientRamp );
694 sl->restoreOldDataDefinedProperties( props );
712 return QStringLiteral(
"GradientFill" );
715void QgsGradientFillSymbolLayer::applyDataDefinedSymbology(
QgsSymbolRenderContext &context,
const QPolygonF &points )
760 if ( currentType == QObject::tr(
"linear" ) )
764 else if ( currentType == QObject::tr(
"radial" ) )
768 else if ( currentType == QObject::tr(
"conical" ) )
782 if ( currentCoordMode == QObject::tr(
"feature" ) )
786 else if ( currentCoordMode == QObject::tr(
"viewport" ) )
800 if ( currentSpread == QObject::tr(
"pad" ) )
804 else if ( currentSpread == QObject::tr(
"repeat" ) )
808 else if ( currentSpread == QObject::tr(
"reflect" ) )
855 if ( refPoint1IsCentroid || refPoint2IsCentroid )
860 QRectF bbox = points.boundingRect();
861 double centroidX = ( centroid.
x() - bbox.left() ) / bbox.width();
862 double centroidY = ( centroid.
y() - bbox.top() ) / bbox.height();
864 if ( refPoint1IsCentroid )
866 refPoint1X = centroidX;
867 refPoint1Y = centroidY;
869 if ( refPoint2IsCentroid )
871 refPoint2X = centroidX;
872 refPoint2Y = centroidY;
878 spread, QPointF( refPoint1X, refPoint1Y ), QPointF( refPoint2X, refPoint2Y ),
angle );
881QPointF QgsGradientFillSymbolLayer::rotateReferencePoint( QPointF refPoint,
double angle )
886 QLineF refLine = QLineF( QPointF( 0.5, 0.5 ), refPoint );
888 refLine.setAngle( refLine.angle() +
angle );
890 QPointF rotatedReferencePoint = refLine.p2();
892 if ( rotatedReferencePoint.x() > 1 )
893 rotatedReferencePoint.setX( 1 );
894 if ( rotatedReferencePoint.x() < 0 )
895 rotatedReferencePoint.setX( 0 );
896 if ( rotatedReferencePoint.y() > 1 )
897 rotatedReferencePoint.setY( 1 );
898 if ( rotatedReferencePoint.y() < 0 )
899 rotatedReferencePoint.setY( 0 );
901 return rotatedReferencePoint;
908 QPointF referencePoint1, QPointF referencePoint2,
const double angle )
913 QColor fillColor2 =
color2;
914 fillColor2.setAlphaF( context.
opacity() * fillColor2.alphaF() );
925 gradient = QLinearGradient( rotatedReferencePoint1, rotatedReferencePoint2 );
928 gradient = QRadialGradient( rotatedReferencePoint1, QLineF( rotatedReferencePoint1, rotatedReferencePoint2 ).length() );
931 gradient = QConicalGradient( rotatedReferencePoint1, QLineF( rotatedReferencePoint1, rotatedReferencePoint2 ).
angle() );
937 gradient.setCoordinateMode( QGradient::ObjectBoundingMode );
940 gradient.setCoordinateMode( QGradient::StretchToDeviceMode );
946 gradient.setSpread( QGradient::PadSpread );
949 gradient.setSpread( QGradient::ReflectSpread );
952 gradient.setSpread( QGradient::RepeatSpread );
968 gradient.setColorAt( 1.0, fillColor2 );
972 brush = QBrush( gradient );
979 selColor.setAlphaF( context.
opacity() );
996 applyDataDefinedSymbology( context, points );
1000 p->setPen( Qt::NoPen );
1033 map[QStringLiteral(
"color_type" )] = QString::number(
static_cast< int >(
mGradientColorType ) );
1034 map[QStringLiteral(
"type" )] = QString::number(
static_cast<int>(
mGradientType ) );
1035 map[QStringLiteral(
"coordinate_mode" )] = QString::number(
static_cast< int >(
mCoordinateMode ) );
1036 map[QStringLiteral(
"spread" )] = QString::number(
static_cast< int >(
mGradientSpread ) );
1041 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
1067 return sl.release();
1109 int blurRadius,
bool useWholeShape,
double maxDistance )
1110 : mBlurRadius( blurRadius )
1111 , mUseWholeShape( useWholeShape )
1112 , mMaxDistance( maxDistance )
1113 , mColorType( colorType )
1132 if ( props.contains( QStringLiteral(
"color_type" ) ) )
1136 if ( props.contains( QStringLiteral(
"shapeburst_color" ) ) )
1141 else if ( props.contains( QStringLiteral(
"color" ) ) )
1146 if ( props.contains( QStringLiteral(
"shapeburst_color2" ) ) )
1151 else if ( props.contains( QStringLiteral(
"gradient_color2" ) ) )
1155 if ( props.contains( QStringLiteral(
"blur_radius" ) ) )
1157 blurRadius = props[QStringLiteral(
"blur_radius" )].toInt();
1159 if ( props.contains( QStringLiteral(
"use_whole_shape" ) ) )
1161 useWholeShape = props[QStringLiteral(
"use_whole_shape" )].toInt();
1163 if ( props.contains( QStringLiteral(
"max_distance" ) ) )
1165 maxDistance = props[QStringLiteral(
"max_distance" )].toDouble();
1167 if ( props.contains( QStringLiteral(
"offset" ) ) )
1186 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
1190 if ( props.contains( QStringLiteral(
"distance_unit" ) ) )
1194 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
1198 if ( props.contains( QStringLiteral(
"distance_map_unit_scale" ) ) )
1202 if ( props.contains( QStringLiteral(
"ignore_rings" ) ) )
1204 sl->setIgnoreRings( props[QStringLiteral(
"ignore_rings" )].toInt() );
1208 sl->setColorRamp( gradientRamp );
1211 sl->restoreOldDataDefinedProperties( props );
1213 return sl.release();
1218 return QStringLiteral(
"ShapeburstFill" );
1228 if ( mGradientRamp.get() == ramp )
1231 mGradientRamp.reset( ramp );
1234void QgsShapeburstFillSymbolLayer::applyDataDefinedSymbology(
QgsSymbolRenderContext &context, QColor &color, QColor &color2,
int &blurRadius,
bool &useWholeShape,
1235 double &maxDistance,
bool &ignoreRings )
1292 selColor.setAlphaF( context.
opacity() );
1293 mSelBrush = QBrush( selColor );
1310 if ( useSelectedColor )
1313 p->setBrush( mSelBrush );
1314 QPointF
offset = mOffset;
1349 int outputPixelMaxDist = 0;
1357 std::unique_ptr< QgsGradientColorRamp > twoColorGradientRamp;
1360 twoColorGradientRamp = std::make_unique< QgsGradientColorRamp >( color1,
color2 );
1364 p->setPen( QPen( Qt::NoPen ) );
1369 int pointsWidth =
static_cast< int >( std::round( points.boundingRect().width() ) );
1370 int pointsHeight =
static_cast< int >( std::round( points.boundingRect().height() ) );
1371 int imWidth = pointsWidth + ( sideBuffer * 2 );
1372 int imHeight = pointsHeight + ( sideBuffer * 2 );
1378 std::unique_ptr< QImage > fillImage = std::make_unique< QImage >( imWidth,
1379 imHeight, QImage::Format_ARGB32_Premultiplied );
1380 if ( fillImage->isNull() )
1390 std::unique_ptr< QImage > alphaImage = std::make_unique< QImage >( fillImage->width(), fillImage->height(), QImage::Format_ARGB32_Premultiplied );
1391 if ( alphaImage->isNull() )
1403 fillImage->fill( Qt::black );
1409 alphaImage->fill( Qt::transparent );
1415 QPainter imgPainter;
1416 imgPainter.begin( alphaImage.get() );
1417 imgPainter.setRenderHint( QPainter::Antialiasing,
true );
1418 imgPainter.setBrush( QBrush( Qt::white ) );
1419 imgPainter.setPen( QPen( Qt::black ) );
1420 imgPainter.translate( -points.boundingRect().left() + sideBuffer, - points.boundingRect().top() + sideBuffer );
1429 imgPainter.begin( fillImage.get() );
1432 imgPainter.drawImage( 0, 0, *alphaImage );
1439 imgPainter.setBrush( QBrush( Qt::white ) );
1440 imgPainter.setPen( QPen( Qt::black ) );
1441 imgPainter.translate( -points.boundingRect().left() + sideBuffer, - points.boundingRect().top() + sideBuffer );
1450 double *dtArray = distanceTransform( fillImage.get(), context.
renderContext() );
1470 imgPainter.begin( fillImage.get() );
1471 imgPainter.setCompositionMode( QPainter::CompositionMode_DestinationIn );
1472 imgPainter.drawImage( 0, 0, *alphaImage );
1480 QPointF
offset = mOffset;
1497 p->drawImage( points.boundingRect().left() - sideBuffer, points.boundingRect().top() - sideBuffer, *fillImage );
1508void QgsShapeburstFillSymbolLayer::distanceTransform1d(
double *f,
int n,
int *v,
double *z,
double *d )
1514 for (
int q = 1; q <= n - 1; q++ )
1516 double s = ( ( f[q] +
static_cast< double >( q ) * q ) - ( f[v[k]] + (
static_cast< double >( v[k] ) * v[k] ) ) ) / ( 2 * q - 2 * v[k] );
1520 s = ( ( f[q] +
static_cast< double >( q ) * q ) - ( f[v[k]] + (
static_cast< double >( v[k] ) * v[k] ) ) ) / ( 2 * q - 2 * v[k] );
1529 for (
int q = 0; q <= n - 1; q++ )
1531 while ( z[k + 1] < q )
1533 d[q] =
static_cast< double >( q - v[k] ) * ( q - v[k] ) + f[v[k]];
1538void QgsShapeburstFillSymbolLayer::distanceTransform2d(
double *im,
int width,
int height,
QgsRenderContext &context )
1540 int maxDimension = std::max( width, height );
1541 double *f =
new double[ maxDimension ];
1542 int *v =
new int[ maxDimension ];
1543 double *z =
new double[ maxDimension + 1 ];
1544 double *d =
new double[ maxDimension ];
1547 for (
int x = 0; x < width; x++ )
1552 for (
int y = 0; y < height; y++ )
1554 f[y] = im[ x +
static_cast< std::size_t
>( y ) * width ];
1556 distanceTransform1d( f, height, v, z, d );
1557 for (
int y = 0; y < height; y++ )
1559 im[ x +
static_cast< std::size_t
>( y ) * width ] = d[y];
1564 for (
int y = 0; y < height; y++ )
1569 for (
int x = 0; x < width; x++ )
1571 f[x] = im[ x +
static_cast< std::size_t
>( y ) * width ];
1573 distanceTransform1d( f, width, v, z, d );
1574 for (
int x = 0; x < width; x++ )
1576 im[ x +
static_cast< std::size_t
>( y ) * width ] = d[x];
1587double *QgsShapeburstFillSymbolLayer::distanceTransform( QImage *im,
QgsRenderContext &context )
1589 int width = im->width();
1590 int height = im->height();
1592 double *dtArray =
new double[
static_cast< std::size_t
>( width ) * height];
1596 std::size_t idx = 0;
1597 for (
int heightIndex = 0; heightIndex < height; ++heightIndex )
1602 const QRgb *scanLine =
reinterpret_cast< const QRgb *
>( im->constScanLine( heightIndex ) );
1603 for (
int widthIndex = 0; widthIndex < width; ++widthIndex )
1605 tmpRgb = scanLine[widthIndex];
1606 if ( qRed( tmpRgb ) == 0 )
1614 dtArray[ idx ] =
INF;
1621 distanceTransform2d( dtArray, width, height, context );
1626void QgsShapeburstFillSymbolLayer::dtArrayToQImage(
double *array, QImage *im,
QgsColorRamp *ramp,
QgsRenderContext &context,
bool useWholeShape,
int maxPixelDistance )
1628 int width = im->width();
1629 int height = im->height();
1632 double maxDistanceValue;
1637 double dtMaxValue = array[0];
1638 for ( std::size_t i = 1; i < static_cast< std::size_t >( width ) * height; ++i )
1640 if ( array[i] > dtMaxValue )
1642 dtMaxValue = array[i];
1647 maxDistanceValue = std::sqrt( dtMaxValue );
1652 maxDistanceValue = maxPixelDistance;
1656 std::size_t idx = 0;
1657 double squaredVal = 0;
1660 for (
int heightIndex = 0; heightIndex < height; ++heightIndex )
1665 QRgb *scanLine =
reinterpret_cast< QRgb *
>( im->scanLine( heightIndex ) );
1666 for (
int widthIndex = 0; widthIndex < width; ++widthIndex )
1669 squaredVal = array[idx];
1672 if ( maxDistanceValue > 0 )
1674 pixVal = squaredVal > 0 ? std::min( ( std::sqrt( squaredVal ) / maxDistanceValue ), 1.0 ) : 0;
1683 scanLine[widthIndex] = qPremultiply( ramp->
color( pixVal ).rgba() );
1694 map[QStringLiteral(
"color_type" )] = QString::number(
static_cast< int >( mColorType ) );
1695 map[QStringLiteral(
"blur_radius" )] = QString::number( mBlurRadius );
1696 map[QStringLiteral(
"use_whole_shape" )] = QString::number( mUseWholeShape );
1697 map[QStringLiteral(
"max_distance" )] = QString::number( mMaxDistance );
1700 map[QStringLiteral(
"ignore_rings" )] = QString::number( mIgnoreRings );
1704 if ( mGradientRamp )
1706 map.insert( mGradientRamp->properties() );
1714 std::unique_ptr< QgsShapeburstFillSymbolLayer > sl = std::make_unique< QgsShapeburstFillSymbolLayer >(
mColor, mColor2, mColorType, mBlurRadius, mUseWholeShape, mMaxDistance );
1715 if ( mGradientRamp )
1717 sl->setColorRamp( mGradientRamp->clone() );
1719 sl->setDistanceUnit( mDistanceUnit );
1720 sl->setDistanceMapUnitScale( mDistanceMapUnitScale );
1721 sl->setIgnoreRings( mIgnoreRings );
1722 sl->setOffset( mOffset );
1723 sl->setOffsetUnit( mOffsetUnit );
1724 sl->setOffsetMapUnitScale( mOffsetMapUnitScale );
1727 return sl.release();
1732 double offsetBleed = context.
convertToPainterUnits( std::max( std::fabs( mOffset.x() ), std::fabs( mOffset.y() ) ), mOffsetUnit, mOffsetMapUnitScale );
1743 mDistanceUnit = unit;
1749 if ( mDistanceUnit == mOffsetUnit )
1751 return mDistanceUnit;
1764 mDistanceMapUnitScale = scale;
1765 mOffsetMapUnitScale = scale;
1770 if ( mDistanceMapUnitScale == mOffsetMapUnitScale )
1772 return mDistanceMapUnitScale;
1797 p->setPen( QPen( Qt::NoPen ) );
1799 QTransform bkTransform =
mBrush.transform();
1803 QTransform t =
mBrush.transform();
1804 t.translate( leftCorner.x(), leftCorner.y() );
1805 mBrush.setTransform( t );
1809 QTransform t =
mBrush.transform();
1810 t.translate( 0, 0 );
1811 mBrush.setTransform( t );
1815 if ( useSelectedColor )
1818 p->setBrush( QBrush( selColor ) );
1824 QTransform t =
mBrush.transform();
1826 mBrush.setTransform( t );
1831 mBrush.setTransform( bkTransform );
1867 return Qt::SolidLine;
1871 return Qt::SolidLine;
1875 return mStroke->dxfPenStyle();
1911 , mPatternWidth( width )
1915 mColor = QColor( 255, 255, 255 );
1921 , mPatternWidth( width )
1922 , mSvgData( svgData )
1927 mColor = QColor( 255, 255, 255 );
1928 setDefaultSvgParams();
1936 mPatternWidthUnit = unit;
1937 mSvgStrokeWidthUnit = unit;
1940 mStroke->setOutputUnit( unit );
1946 if ( mPatternWidthUnit != unit || mSvgStrokeWidthUnit != unit ||
mStrokeWidthUnit != unit )
1956 mPatternWidthMapUnitScale = scale;
1957 mSvgStrokeWidthMapUnitScale = scale;
1963 mPatternWidthMapUnitScale == mSvgStrokeWidthMapUnitScale &&
1966 return mPatternWidthMapUnitScale;
1976 mSvgFilePath = svgPath;
1977 setDefaultSvgParams();
1987 if (
properties.contains( QStringLiteral(
"width" ) ) )
1989 width =
properties[QStringLiteral(
"width" )].toDouble();
1991 if (
properties.contains( QStringLiteral(
"svgFile" ) ) )
1995 if (
properties.contains( QStringLiteral(
"angle" ) ) )
2000 std::unique_ptr< QgsSVGFillSymbolLayer > symbolLayer;
2003 symbolLayer = std::make_unique< QgsSVGFillSymbolLayer >(
svgFilePath, width,
angle );
2007 if (
properties.contains( QStringLiteral(
"data" ) ) )
2009 data = QByteArray::fromHex(
properties[QStringLiteral(
"data" )].toString().toLocal8Bit() );
2011 symbolLayer = std::make_unique< QgsSVGFillSymbolLayer >( data, width,
angle );
2015 if (
properties.contains( QStringLiteral(
"svgFillColor" ) ) )
2020 else if (
properties.contains( QStringLiteral(
"color" ) ) )
2024 if (
properties.contains( QStringLiteral(
"svgOutlineColor" ) ) )
2029 else if (
properties.contains( QStringLiteral(
"outline_color" ) ) )
2033 else if (
properties.contains( QStringLiteral(
"line_color" ) ) )
2037 if (
properties.contains( QStringLiteral(
"svgOutlineWidth" ) ) )
2040 symbolLayer->setSvgStrokeWidth(
properties[QStringLiteral(
"svgOutlineWidth" )].toDouble() );
2042 else if (
properties.contains( QStringLiteral(
"outline_width" ) ) )
2044 symbolLayer->setSvgStrokeWidth(
properties[QStringLiteral(
"outline_width" )].toDouble() );
2046 else if (
properties.contains( QStringLiteral(
"line_width" ) ) )
2048 symbolLayer->setSvgStrokeWidth(
properties[QStringLiteral(
"line_width" )].toDouble() );
2052 if (
properties.contains( QStringLiteral(
"pattern_width_unit" ) ) )
2056 if (
properties.contains( QStringLiteral(
"pattern_width_map_unit_scale" ) ) )
2060 if (
properties.contains( QStringLiteral(
"svg_outline_width_unit" ) ) )
2064 if (
properties.contains( QStringLiteral(
"svg_outline_width_map_unit_scale" ) ) )
2068 if (
properties.contains( QStringLiteral(
"outline_width_unit" ) ) )
2072 if (
properties.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
2077 if (
properties.contains( QStringLiteral(
"parameters" ) ) )
2083 symbolLayer->restoreOldDataDefinedProperties(
properties );
2085 return symbolLayer.release();
2090 QVariantMap::iterator it =
properties.find( QStringLiteral(
"svgFile" ) );
2102 return QStringLiteral(
"SVGFill" );
2105void QgsSVGFillSymbolLayer::applyPattern( QBrush &brush,
const QString &svgFilePath,
double patternWidth,
Qgis::RenderUnit patternWidthUnit,
2106 const QColor &svgFillColor,
const QColor &svgStrokeColor,
double svgStrokeWidth,
2110 if ( mSvgViewBox.isNull() )
2117 if (
static_cast< int >( size ) < 1.0 || 10000.0 < size )
2119 brush.setTextureImage( QImage() );
2123 bool fitsInCache =
true;
2131 double hwRatio = 1.0;
2132 if ( patternPict.width() > 0 )
2134 hwRatio =
static_cast< double >( patternPict.height() ) /
static_cast< double >( patternPict.width() );
2136 patternImage = QImage(
static_cast< int >( size ),
static_cast< int >( size * hwRatio ), QImage::Format_ARGB32_Premultiplied );
2137 patternImage.fill( 0 );
2139 QPainter p( &patternImage );
2140 p.drawPicture( QPointF( size / 2, size * hwRatio / 2 ), patternPict );
2143 QTransform brushTransform;
2146 QImage transparentImage = patternImage.copy();
2148 brush.setTextureImage( transparentImage );
2152 brush.setTextureImage( patternImage );
2154 brush.setTransform( brushTransform );
2162 applyPattern(
mBrush, mSvgFilePath, mPatternWidth, mPatternWidthUnit,
mColor, mSvgStrokeColor, mSvgStrokeWidth, mSvgStrokeWidthUnit, context, mPatternWidthMapUnitScale, mSvgStrokeWidthMapUnitScale, evaluatedParameters );
2186 mStroke->renderPolyline( points, context.
feature(), context.
renderContext(), -1, useSelectedColor );
2189 for (
auto ringIt = rings->constBegin(); ringIt != rings->constEnd(); ++ringIt )
2191 mStroke->renderPolyline( *ringIt, context.
feature(), context.
renderContext(), -1, useSelectedColor );
2200 if ( !mSvgFilePath.isEmpty() )
2202 map.insert( QStringLiteral(
"svgFile" ), mSvgFilePath );
2206 map.insert( QStringLiteral(
"data" ), QString( mSvgData.toHex() ) );
2209 map.insert( QStringLiteral(
"width" ), QString::number( mPatternWidth ) );
2210 map.insert( QStringLiteral(
"angle" ), QString::number(
mAngle ) );
2215 map.insert( QStringLiteral(
"outline_width" ), QString::number( mSvgStrokeWidth ) );
2232 std::unique_ptr< QgsSVGFillSymbolLayer > clonedLayer;
2233 if ( !mSvgFilePath.isEmpty() )
2235 clonedLayer = std::make_unique< QgsSVGFillSymbolLayer >( mSvgFilePath, mPatternWidth,
mAngle );
2236 clonedLayer->setSvgFillColor(
mColor );
2237 clonedLayer->setSvgStrokeColor( mSvgStrokeColor );
2238 clonedLayer->setSvgStrokeWidth( mSvgStrokeWidth );
2242 clonedLayer = std::make_unique< QgsSVGFillSymbolLayer >( mSvgData, mPatternWidth,
mAngle );
2245 clonedLayer->setPatternWidthUnit( mPatternWidthUnit );
2246 clonedLayer->setPatternWidthMapUnitScale( mPatternWidthMapUnitScale );
2247 clonedLayer->setSvgStrokeWidthUnit( mSvgStrokeWidthUnit );
2248 clonedLayer->setSvgStrokeWidthMapUnitScale( mSvgStrokeWidthMapUnitScale );
2252 clonedLayer->setParameters( mParameters );
2256 clonedLayer->setSubSymbol( mStroke->clone() );
2260 return clonedLayer.release();
2265 QDomElement symbolizerElem = doc.createElement( QStringLiteral(
"se:PolygonSymbolizer" ) );
2266 if ( !props.value( QStringLiteral(
"uom" ), QString() ).toString().isEmpty() )
2267 symbolizerElem.setAttribute( QStringLiteral(
"uom" ), props.value( QStringLiteral(
"uom" ), QString() ).toString() );
2268 element.appendChild( symbolizerElem );
2272 QDomElement fillElem = doc.createElement( QStringLiteral(
"se:Fill" ) );
2273 symbolizerElem.appendChild( fillElem );
2275 QDomElement graphicFillElem = doc.createElement( QStringLiteral(
"se:GraphicFill" ) );
2276 fillElem.appendChild( graphicFillElem );
2278 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
2279 graphicFillElem.appendChild( graphicElem );
2281 if ( !mSvgFilePath.isEmpty() )
2292 symbolizerElem.appendChild( doc.createComment( QStringLiteral(
"SVG from data not implemented yet" ) ) );
2298 double angle = props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toDouble( &ok );
2301 angleFunc = QStringLiteral(
"%1 + %2" ).arg( props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toString() ).arg(
mAngle );
2314 mStroke->toSld( doc, element, props );
2326 return mStroke.get();
2333 mStroke.reset(
nullptr );
2346 mStroke.reset( lineSymbol );
2356 if ( mStroke && mStroke->symbolLayer( 0 ) )
2358 double subLayerBleed = mStroke->symbolLayer( 0 )->estimateMaxBleed( context );
2359 return subLayerBleed;
2369 return QColor( Qt::black );
2371 return mStroke->color();
2378 attr.unite( mStroke->usedAttributes( context ) );
2386 if ( mStroke && mStroke->hasDataDefinedProperties() )
2393 QString path, mimeType;
2395 Qt::PenStyle penStyle;
2396 double size, strokeWidth;
2398 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
2399 if ( fillElem.isNull() )
2402 QDomElement graphicFillElem = fillElem.firstChildElement( QStringLiteral(
"GraphicFill" ) );
2403 if ( graphicFillElem.isNull() )
2406 QDomElement graphicElem = graphicFillElem.firstChildElement( QStringLiteral(
"Graphic" ) );
2407 if ( graphicElem.isNull() )
2413 if ( mimeType != QLatin1String(
"image/svg+xml" ) )
2418 double scaleFactor = 1.0;
2419 const QString uom = element.attribute( QStringLiteral(
"uom" ) );
2421 size = size * scaleFactor;
2422 strokeWidth = strokeWidth * scaleFactor;
2429 double d = angleFunc.toDouble( &ok );
2434 std::unique_ptr< QgsSVGFillSymbolLayer > sl = std::make_unique< QgsSVGFillSymbolLayer >( path, size,
angle );
2435 sl->setOutputUnit( sldUnitSize );
2438 sl->setSvgStrokeWidth( strokeWidth );
2441 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
2442 if ( !strokeElem.isNull() )
2453 return sl.release();
2471 double width = mPatternWidth;
2477 QString svgFile = mSvgFilePath;
2496 double strokeWidth = mSvgStrokeWidth;
2505 mSvgStrokeWidthUnit, context, mPatternWidthMapUnitScale, mSvgStrokeWidthMapUnitScale, evaluatedParameters );
2509void QgsSVGFillSymbolLayer::storeViewBox()
2511 if ( !mSvgData.isEmpty() )
2513 QSvgRenderer r( mSvgData );
2516 mSvgViewBox = r.viewBoxF();
2521 mSvgViewBox = QRectF();
2524void QgsSVGFillSymbolLayer::setDefaultSvgParams()
2526 if ( mSvgFilePath.isEmpty() )
2531 bool hasFillParam, hasFillOpacityParam, hasStrokeParam, hasStrokeWidthParam, hasStrokeOpacityParam;
2532 bool hasDefaultFillColor, hasDefaultFillOpacity, hasDefaultStrokeColor, hasDefaultStrokeWidth, hasDefaultStrokeOpacity;
2533 QColor defaultFillColor, defaultStrokeColor;
2534 double defaultStrokeWidth, defaultFillOpacity, defaultStrokeOpacity;
2536 hasFillOpacityParam, hasDefaultFillOpacity, defaultFillOpacity,
2537 hasStrokeParam, hasDefaultStrokeColor, defaultStrokeColor,
2538 hasStrokeWidthParam, hasDefaultStrokeWidth, defaultStrokeWidth,
2539 hasStrokeOpacityParam, hasDefaultStrokeOpacity, defaultStrokeOpacity );
2541 double newFillOpacity = hasFillOpacityParam ?
mColor.alphaF() : 1.0;
2542 double newStrokeOpacity = hasStrokeOpacityParam ? mSvgStrokeColor.alphaF() : 1.0;
2544 if ( hasDefaultFillColor )
2546 mColor = defaultFillColor;
2547 mColor.setAlphaF( newFillOpacity );
2549 if ( hasDefaultFillOpacity )
2551 mColor.setAlphaF( defaultFillOpacity );
2553 if ( hasDefaultStrokeColor )
2555 mSvgStrokeColor = defaultStrokeColor;
2556 mSvgStrokeColor.setAlphaF( newStrokeOpacity );
2558 if ( hasDefaultStrokeOpacity )
2560 mSvgStrokeColor.setAlphaF( defaultStrokeOpacity );
2562 if ( hasDefaultStrokeWidth )
2564 mSvgStrokeWidth = defaultStrokeWidth;
2577 mFillLineSymbol = std::make_unique<QgsLineSymbol>( );
2585 mFillLineSymbol->setWidth( w );
2591 mFillLineSymbol->setColor(
c );
2597 return mFillLineSymbol ? mFillLineSymbol->color() :
mColor;
2609 mFillLineSymbol.reset( qgis::down_cast<QgsLineSymbol *>( symbol ) );
2618 return mFillLineSymbol.get();
2624 if ( mFillLineSymbol )
2625 attr.unite( mFillLineSymbol->usedAttributes( context ) );
2633 if ( mFillLineSymbol && mFillLineSymbol->hasDataDefinedProperties() )
2655 double lineAngleRad { qDegreesToRadians( mLineAngle ) };
2657 const int quadrant {
static_cast<int>( lineAngleRad / M_PI_2 ) };
2658 Q_ASSERT( quadrant >= 0 && quadrant <= 3 );
2668 lineAngleRad -= M_PI / 2;
2673 lineAngleRad -= M_PI;
2678 lineAngleRad -= M_PI + M_PI_2;
2686 QSize size {
static_cast<int>( distancePx ),
static_cast<int>( distancePx ) };
2688 if (
static_cast<int>( mLineAngle ) % 90 != 0 )
2690 size = QSize(
static_cast<int>( distancePx / std::sin( lineAngleRad ) ),
static_cast<int>( distancePx / std::cos( lineAngleRad ) ) );
2693 QPixmap pixmap( size );
2694 pixmap.fill( Qt::transparent );
2696 painter.begin( &pixmap );
2697 painter.setRenderHint( QPainter::Antialiasing );
2705 std::unique_ptr< QgsLinePatternFillSymbolLayer > layerClone(
clone() );
2706 layerClone->setOffset( 0 );
2707 layerClone->drawPreviewIcon( symbolContext, pixmap.size() );
2709 return pixmap.toImage();
2720 mDistanceUnit = unit;
2721 mLineWidthUnit = unit;
2724 if ( mFillLineSymbol )
2725 mFillLineSymbol->setOutputUnit( unit );
2748 mDistanceMapUnitScale = scale;
2749 mLineWidthMapUnitScale = scale;
2750 mOffsetMapUnitScale = scale;
2756 mDistanceMapUnitScale == mLineWidthMapUnitScale &&
2757 mLineWidthMapUnitScale == mOffsetMapUnitScale )
2759 return mDistanceMapUnitScale;
2766 std::unique_ptr< QgsLinePatternFillSymbolLayer > patternLayer = std::make_unique< QgsLinePatternFillSymbolLayer >();
2772 QColor
color( Qt::black );
2775 if (
properties.contains( QStringLiteral(
"lineangle" ) ) )
2780 else if (
properties.contains( QStringLiteral(
"angle" ) ) )
2784 patternLayer->setLineAngle(
lineAngle );
2786 if (
properties.contains( QStringLiteral(
"distance" ) ) )
2790 patternLayer->setDistance(
distance );
2792 if (
properties.contains( QStringLiteral(
"linewidth" ) ) )
2797 else if (
properties.contains( QStringLiteral(
"outline_width" ) ) )
2801 else if (
properties.contains( QStringLiteral(
"line_width" ) ) )
2805 patternLayer->setLineWidth(
lineWidth );
2807 if (
properties.contains( QStringLiteral(
"color" ) ) )
2811 else if (
properties.contains( QStringLiteral(
"outline_color" ) ) )
2815 else if (
properties.contains( QStringLiteral(
"line_color" ) ) )
2819 patternLayer->setColor(
color );
2821 if (
properties.contains( QStringLiteral(
"offset" ) ) )
2825 patternLayer->setOffset(
offset );
2828 if (
properties.contains( QStringLiteral(
"distance_unit" ) ) )
2832 if (
properties.contains( QStringLiteral(
"distance_map_unit_scale" ) ) )
2836 if (
properties.contains( QStringLiteral(
"line_width_unit" ) ) )
2840 else if (
properties.contains( QStringLiteral(
"outline_width_unit" ) ) )
2844 if (
properties.contains( QStringLiteral(
"line_width_map_unit_scale" ) ) )
2848 if (
properties.contains( QStringLiteral(
"offset_unit" ) ) )
2852 if (
properties.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
2856 if (
properties.contains( QStringLiteral(
"outline_width_unit" ) ) )
2860 if (
properties.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
2864 if (
properties.contains( QStringLiteral(
"coordinate_reference" ) ) )
2868 if (
properties.contains( QStringLiteral(
"clip_mode" ) ) )
2873 patternLayer->restoreOldDataDefinedProperties(
properties );
2875 return patternLayer.release();
2880 return QStringLiteral(
"LinePatternFill" );
2883bool QgsLinePatternFillSymbolLayer::applyPattern(
const QgsSymbolRenderContext &context, QBrush &brush,
double lineAngle,
double distance )
2885 mBrush.setTextureImage( QImage() );
2887 if ( !mFillLineSymbol )
2892 std::unique_ptr< QgsLineSymbol > fillLineSymbol( mFillLineSymbol->clone() );
2893 if ( !fillLineSymbol )
2909 outputPixelOffset = std::fmod( outputPixelOffset, outputPixelDist );
2910 if ( outputPixelOffset > outputPixelDist / 2.0 )
2911 outputPixelOffset -= outputPixelDist;
2915 double outputPixelBleed = 0;
2916 double outputPixelInterval = 0;
2917 for (
int i = 0; i < fillLineSymbol->symbolLayerCount(); i++ )
2921 outputPixelBleed = std::max( outputPixelBleed, outputPixelLayerBleed );
2924 if ( markerLineLayer )
2933 outputPixelInterval = std::max( outputPixelInterval, outputPixelLayerInterval );
2937 if ( outputPixelInterval > 0 )
2941 double intervalScale = std::round( outputPixelInterval ) / outputPixelInterval;
2942 outputPixelInterval = std::round( outputPixelInterval );
2944 for (
int i = 0; i < fillLineSymbol->symbolLayerCount(); i++ )
2949 if ( markerLineLayer )
2963 height = outputPixelDist;
2964 width = outputPixelInterval > 0 ? outputPixelInterval : height;
2968 width = outputPixelDist;
2969 height = outputPixelInterval > 0 ? outputPixelInterval : width;
2973 height = outputPixelDist / std::cos(
lineAngle * M_PI / 180 );
2974 width = outputPixelDist / std::sin(
lineAngle * M_PI / 180 );
2977 lineAngle = 180 * std::atan2(
static_cast< double >( height ),
static_cast< double >( width ) ) / M_PI;
2983 height = std::abs( height );
2984 width = std::abs( width );
2986 outputPixelDist = std::abs( height * std::cos(
lineAngle * M_PI / 180 ) );
2990 int offsetHeight =
static_cast< int >( std::round( outputPixelOffset / std::cos(
lineAngle * M_PI / 180 ) ) );
2991 outputPixelOffset = offsetHeight * std::cos(
lineAngle * M_PI / 180 );
3000 int bufferMulti =
static_cast< int >( std::max( std::ceil( outputPixelBleed / width ), std::ceil( outputPixelBleed / width ) ) );
3004 bufferMulti = std::max( bufferMulti, 1 );
3006 int xBuffer = width * bufferMulti;
3007 int yBuffer = height * bufferMulti;
3008 int innerWidth = width;
3009 int innerHeight = height;
3010 width += 2 * xBuffer;
3011 height += 2 * yBuffer;
3014 if ( width > 2000 || height > 2000 || width == 0 || height == 0 )
3019 QImage patternImage( width, height, QImage::Format_ARGB32 );
3020 patternImage.fill( 0 );
3022 QPointF p1, p2, p3, p4, p5, p6;
3025 p1 = QPointF( 0, yBuffer );
3026 p2 = QPointF( width, yBuffer );
3027 p3 = QPointF( 0, yBuffer + innerHeight );
3028 p4 = QPointF( width, yBuffer + innerHeight );
3032 p1 = QPointF( xBuffer, height );
3033 p2 = QPointF( xBuffer, 0 );
3034 p3 = QPointF( xBuffer + innerWidth, height );
3035 p4 = QPointF( xBuffer + innerWidth, 0 );
3039 dx = outputPixelDist * std::cos( ( 90 -
lineAngle ) * M_PI / 180.0 );
3040 dy = outputPixelDist * std::sin( ( 90 -
lineAngle ) * M_PI / 180.0 );
3041 p1 = QPointF( 0, height );
3042 p2 = QPointF( width, 0 );
3043 p3 = QPointF( -dx, height - dy );
3044 p4 = QPointF( width - dx, -dy );
3045 p5 = QPointF( dx, height + dy );
3046 p6 = QPointF( width + dx, dy );
3050 dx = outputPixelDist * std::cos( ( 90 -
lineAngle ) * M_PI / 180.0 );
3051 dy = outputPixelDist * std::sin( ( 90 -
lineAngle ) * M_PI / 180.0 );
3052 p1 = QPointF( width, 0 );
3053 p2 = QPointF( 0, height );
3054 p3 = QPointF( width - dx, -dy );
3055 p4 = QPointF( -dx, height - dy );
3056 p5 = QPointF( width + dx, dy );
3057 p6 = QPointF( dx, height + dy );
3061 dy = outputPixelDist * std::cos( ( 180 -
lineAngle ) * M_PI / 180 );
3062 dx = outputPixelDist * std::sin( ( 180 -
lineAngle ) * M_PI / 180 );
3063 p1 = QPointF( 0, 0 );
3064 p2 = QPointF( width, height );
3065 p5 = QPointF( dx, -dy );
3066 p6 = QPointF( width + dx, height - dy );
3067 p3 = QPointF( -dx, dy );
3068 p4 = QPointF( width - dx, height + dy );
3072 dy = outputPixelDist * std::cos( ( 180 -
lineAngle ) * M_PI / 180 );
3073 dx = outputPixelDist * std::sin( ( 180 -
lineAngle ) * M_PI / 180 );
3074 p1 = QPointF( width, height );
3075 p2 = QPointF( 0, 0 );
3076 p5 = QPointF( width + dx, height - dy );
3077 p6 = QPointF( dx, -dy );
3078 p3 = QPointF( width - dx, height + dy );
3079 p4 = QPointF( -dx, dy );
3086 p3 = QPointF( tempPt.x(), tempPt.y() );
3088 p4 = QPointF( tempPt.x(), tempPt.y() );
3090 p5 = QPointF( tempPt.x(), tempPt.y() );
3092 p6 = QPointF( tempPt.x(), tempPt.y() );
3096 p1 = QPointF( tempPt.x(), tempPt.y() );
3098 p2 = QPointF( tempPt.x(), tempPt.y() );
3101 QPainter p( &patternImage );
3105 p.setRenderHint( QPainter::Antialiasing,
false );
3106 QPen pen( QColor( Qt::black ) );
3107 pen.setWidthF( 0.1 );
3108 pen.setCapStyle( Qt::FlatCap );
3113 QPolygon polygon = QPolygon() << QPoint( 0, 0 ) << QPoint( width - 1, 0 ) << QPoint( width - 1, height - 1 ) << QPoint( 0, height - 1 ) << QPoint( 0, 0 );
3114 p.drawPolygon( polygon );
3116 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 );
3117 p.drawPolygon( polygon );
3123 p.setRenderHint( QPainter::Antialiasing,
true );
3137 fillLineSymbol->startRender( lineRenderContext, context.
fields() );
3139 QVector<QPolygonF> polygons;
3140 polygons.append( QPolygonF() << p1 << p2 );
3141 polygons.append( QPolygonF() << p3 << p4 );
3144 polygons.append( QPolygonF() << p5 << p6 );
3148 for (
const QPolygonF &polygon : std::as_const( polygons ) )
3150 fillLineSymbol->renderPolyline( polygon, context.
feature(), lineRenderContext, -1, useSelectedColor );
3153 fillLineSymbol->stopRender( lineRenderContext );
3157 patternImage = patternImage.copy( xBuffer, yBuffer, patternImage.width() - 2 * xBuffer, patternImage.height() - 2 * yBuffer );
3162 QImage transparentImage = patternImage.copy();
3164 brush.setTextureImage( transparentImage );
3168 brush.setTextureImage( patternImage );
3171 QTransform brushTransform;
3172 brush.setTransform( brushTransform );
3182 || ( mFillLineSymbol && mFillLineSymbol->hasDataDefinedProperties() )
3186 if ( !mRenderUsingLines )
3190 mRenderUsingLines = !applyPattern( context,
mBrush, mLineAngle, mDistance );
3193 if ( mRenderUsingLines && mFillLineSymbol )
3197 mFillLineSymbolRenderStarted =
true;
3203 if ( mFillLineSymbolRenderStarted )
3206 mFillLineSymbolRenderStarted =
false;
3213 if ( !useSelectedColor && !mRenderUsingLines )
3220 if ( !mFillLineSymbolRenderStarted && mFillLineSymbol )
3224 mFillLineSymbolRenderStarted =
true;
3254 outputPixelOffset = std::fmod( outputPixelOffset, outputPixelDistance );
3255 if ( outputPixelOffset > outputPixelDistance / 2.0 )
3256 outputPixelOffset -= outputPixelDistance;
3258 p->setPen( QPen( Qt::NoPen ) );
3280 std::unique_ptr< QgsPolygon > shapePolygon;
3281 std::unique_ptr< QgsGeometryEngine > shapeEngine;
3289 shapePolygon = std::make_unique< QgsPolygon >();
3291 shapePolygon->setExteriorRing( fromPolygon.release() );
3294 for (
const QPolygonF &ring : *rings )
3297 shapePolygon->addInteriorRing( fromRing.release() );
3301 shapeEngine->prepareGeometry();
3308 path.addPolygon( points );
3311 for (
const QPolygonF &ring : *rings )
3313 path.addPolygon( ring );
3316 p->setClipPath( path, Qt::IntersectClip );
3322 const QRectF boundingRect = points.boundingRect();
3324 QTransform invertedRotateTransform;
3330 QTransform transform;
3331 if ( applyBrushTransform )
3334 transform.translate( -boundingRect.center().x(),
3335 -boundingRect.center().y() );
3337 transform.translate( boundingRect.center().x(),
3338 boundingRect.center().y() );
3346 const QRectF transformedBounds = transform.map( points ).boundingRect();
3350 left = transformedBounds.left() - buffer * 2;
3351 top = transformedBounds.top() - buffer * 2;
3352 right = transformedBounds.right() + buffer * 2;
3353 bottom = transformedBounds.bottom() + buffer * 2;
3354 invertedRotateTransform = transform.inverted();
3356 if ( !applyBrushTransform )
3358 top -= transformedBounds.top() - ( outputPixelDistance * std::floor( transformedBounds.top() / outputPixelDistance ) );
3363 const bool needsExpressionContext = mFillLineSymbol->hasDataDefinedProperties();
3368 int currentLine = 0;
3369 for (
double currentY = top; currentY <= bottom; currentY += outputPixelDistance )
3374 if ( needsExpressionContext )
3378 double y1 = currentY;
3380 double y2 = currentY;
3381 invertedRotateTransform.map( left, currentY - outputPixelOffset, &x1, &y1 );
3382 invertedRotateTransform.map( right, currentY - outputPixelOffset, &x2, &y2 );
3387 std::unique_ptr< QgsAbstractGeometry > intersection( shapeEngine->intersection( &ls ) );
3388 for (
auto it = intersection->const_parts_begin(); it != intersection->const_parts_end(); ++it )
3390 if (
const QgsLineString *ls = qgsgeometry_cast< const QgsLineString * >( *it ) )
3398 mFillLineSymbol->renderPolyline( QPolygonF() << QPointF( x1, y1 ) << QPointF( x2, y2 ), context.
feature(), context.
renderContext(), -1, useSelectedColor );
3410 map.insert( QStringLiteral(
"angle" ), QString::number( mLineAngle ) );
3411 map.insert( QStringLiteral(
"distance" ), QString::number( mDistance ) );
3412 map.insert( QStringLiteral(
"line_width" ), QString::number( mLineWidth ) );
3414 map.insert( QStringLiteral(
"offset" ), QString::number( mOffset ) );
3430 if ( mFillLineSymbol )
3441 QDomElement symbolizerElem = doc.createElement( QStringLiteral(
"se:PolygonSymbolizer" ) );
3442 if ( !props.value( QStringLiteral(
"uom" ), QString() ).toString().isEmpty() )
3443 symbolizerElem.setAttribute( QStringLiteral(
"uom" ), props.value( QStringLiteral(
"uom" ), QString() ).toString() );
3444 element.appendChild( symbolizerElem );
3449 QDomElement fillElem = doc.createElement( QStringLiteral(
"se:Fill" ) );
3450 symbolizerElem.appendChild( fillElem );
3452 QDomElement graphicFillElem = doc.createElement( QStringLiteral(
"se:GraphicFill" ) );
3453 fillElem.appendChild( graphicFillElem );
3455 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
3456 graphicFillElem.appendChild( graphicElem );
3461 bool exportOk {
false };
3465 if ( ! image.isNull() )
3467 const QFileInfo info { context.exportFilePath() };
3468 QString pngPath { info.completeSuffix().isEmpty() ? context.exportFilePath() : context.exportFilePath().chopped( info.completeSuffix().length() ).append( QStringLiteral(
"png" ) ) };
3470 image.save( pngPath );
3479 QColor lineColor = mFillLineSymbol ? mFillLineSymbol->color() : QColor();
3480 double lineWidth = mFillLineSymbol ? mFillLineSymbol->width() : 0.0;
3488 double angle = props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toDouble( &ok );
3491 angleFunc = QStringLiteral(
"%1 + %2" ).arg( props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toString() ).arg( mLineAngle );
3495 angleFunc = QString::number(
angle + mLineAngle );
3500 QPointF lineOffset( std::sin( mLineAngle ) * mOffset, std::cos( mLineAngle ) * mOffset );
3508 QString featureStyle;
3509 featureStyle.append(
"Brush(" );
3510 featureStyle.append( QStringLiteral(
"fc:%1" ).arg(
mColor.name() ) );
3511 featureStyle.append( QStringLiteral(
",bc:%1" ).arg( QLatin1String(
"#00000000" ) ) );
3512 featureStyle.append(
",id:\"ogr-brush-2\"" );
3513 featureStyle.append( QStringLiteral(
",a:%1" ).arg( mLineAngle ) );
3514 featureStyle.append( QStringLiteral(
",s:%1" ).arg( mLineWidth * widthScaleFactor ) );
3515 featureStyle.append(
",dx:0mm" );
3516 featureStyle.append( QStringLiteral(
",dy:%1mm" ).arg( mDistance * widthScaleFactor ) );
3517 featureStyle.append(
')' );
3518 return featureStyle;
3524 && ( !mFillLineSymbol || !mFillLineSymbol->hasDataDefinedProperties() ) )
3549 Qt::PenStyle lineStyle;
3551 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
3552 if ( fillElem.isNull() )
3555 QDomElement graphicFillElem = fillElem.firstChildElement( QStringLiteral(
"GraphicFill" ) );
3556 if ( graphicFillElem.isNull() )
3559 QDomElement graphicElem = graphicFillElem.firstChildElement( QStringLiteral(
"Graphic" ) );
3560 if ( graphicElem.isNull() )
3566 if ( name != QLatin1String(
"horline" ) )
3574 double d = angleFunc.toDouble( &ok );
3583 offset = std::sqrt( std::pow( vectOffset.x(), 2 ) + std::pow( vectOffset.y(), 2 ) );
3586 double scaleFactor = 1.0;
3587 const QString uom = element.attribute( QStringLiteral(
"uom" ) );
3589 size = size * scaleFactor;
3592 std::unique_ptr< QgsLinePatternFillSymbolLayer > sl = std::make_unique< QgsLinePatternFillSymbolLayer >();
3593 sl->setOutputUnit( sldUnitSize );
3594 sl->setColor( lineColor );
3596 sl->setLineAngle(
angle );
3598 sl->setDistance( size );
3601 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
3602 if ( !strokeElem.isNull() )
3613 return sl.release();
3713 std::unique_ptr< QgsPointPatternFillSymbolLayer > layer = std::make_unique< QgsPointPatternFillSymbolLayer >();
3714 if (
properties.contains( QStringLiteral(
"distance_x" ) ) )
3716 layer->setDistanceX(
properties[QStringLiteral(
"distance_x" )].toDouble() );
3718 if (
properties.contains( QStringLiteral(
"distance_y" ) ) )
3720 layer->setDistanceY(
properties[QStringLiteral(
"distance_y" )].toDouble() );
3722 if (
properties.contains( QStringLiteral(
"displacement_x" ) ) )
3724 layer->setDisplacementX(
properties[QStringLiteral(
"displacement_x" )].toDouble() );
3726 if (
properties.contains( QStringLiteral(
"displacement_y" ) ) )
3728 layer->setDisplacementY(
properties[QStringLiteral(
"displacement_y" )].toDouble() );
3730 if (
properties.contains( QStringLiteral(
"offset_x" ) ) )
3732 layer->setOffsetX(
properties[QStringLiteral(
"offset_x" )].toDouble() );
3734 if (
properties.contains( QStringLiteral(
"offset_y" ) ) )
3736 layer->setOffsetY(
properties[QStringLiteral(
"offset_y" )].toDouble() );
3739 if (
properties.contains( QStringLiteral(
"distance_x_unit" ) ) )
3743 if (
properties.contains( QStringLiteral(
"distance_x_map_unit_scale" ) ) )
3747 if (
properties.contains( QStringLiteral(
"distance_y_unit" ) ) )
3751 if (
properties.contains( QStringLiteral(
"distance_y_map_unit_scale" ) ) )
3755 if (
properties.contains( QStringLiteral(
"displacement_x_unit" ) ) )
3759 if (
properties.contains( QStringLiteral(
"displacement_x_map_unit_scale" ) ) )
3763 if (
properties.contains( QStringLiteral(
"displacement_y_unit" ) ) )
3767 if (
properties.contains( QStringLiteral(
"displacement_y_map_unit_scale" ) ) )
3771 if (
properties.contains( QStringLiteral(
"offset_x_unit" ) ) )
3775 if (
properties.contains( QStringLiteral(
"offset_x_map_unit_scale" ) ) )
3779 if (
properties.contains( QStringLiteral(
"offset_y_unit" ) ) )
3783 if (
properties.contains( QStringLiteral(
"offset_y_map_unit_scale" ) ) )
3788 if (
properties.contains( QStringLiteral(
"random_deviation_x" ) ) )
3790 layer->setMaximumRandomDeviationX(
properties[QStringLiteral(
"random_deviation_x" )].toDouble() );
3792 if (
properties.contains( QStringLiteral(
"random_deviation_y" ) ) )
3794 layer->setMaximumRandomDeviationY(
properties[QStringLiteral(
"random_deviation_y" )].toDouble() );
3796 if (
properties.contains( QStringLiteral(
"random_deviation_x_unit" ) ) )
3800 if (
properties.contains( QStringLiteral(
"random_deviation_x_map_unit_scale" ) ) )
3804 if (
properties.contains( QStringLiteral(
"random_deviation_y_unit" ) ) )
3808 if (
properties.contains( QStringLiteral(
"random_deviation_y_map_unit_scale" ) ) )
3812 unsigned long seed = 0;
3813 if (
properties.contains( QStringLiteral(
"seed" ) ) )
3819 std::random_device rd;
3820 std::mt19937 mt(
seed == 0 ? rd() :
seed );
3821 std::uniform_int_distribution<> uniformDist( 1, 999999999 );
3822 seed = uniformDist( mt );
3824 layer->setSeed(
seed );
3826 if (
properties.contains( QStringLiteral(
"outline_width_unit" ) ) )
3830 if (
properties.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
3834 if (
properties.contains( QStringLiteral(
"clip_mode" ) ) )
3838 if (
properties.contains( QStringLiteral(
"coordinate_reference" ) ) )
3843 if (
properties.contains( QStringLiteral(
"angle" ) ) )
3845 layer->setAngle(
properties[QStringLiteral(
"angle" )].toDouble() );
3848 layer->restoreOldDataDefinedProperties(
properties );
3850 return layer.release();
3855 return QStringLiteral(
"PointPatternFill" );
3858bool QgsPointPatternFillSymbolLayer::applyPattern(
const QgsSymbolRenderContext &context, QBrush &brush,
double distanceX,
double distanceY,
3859 double displacementX,
double displacementY,
double offsetX,
double offsetY )
3866 double widthOffset = std::fmod(
3869 double heightOffset = std::fmod(
3873 if ( width > 2000 || height > 2000 )
3875 brush.setTextureImage( QImage() );
3879 QImage patternImage( width, height, QImage::Format_ARGB32 );
3880 patternImage.fill( 0 );
3881 if ( patternImage.isNull() )
3883 brush.setTextureImage( QImage() );
3888 QPainter p( &patternImage );
3907 for (
double currentX = -width; currentX <= width * 2.0; currentX += width )
3909 for (
double currentY = -height; currentY <= height * 2.0; currentY += height )
3911 mMarkerSymbol->renderPoint( QPointF( currentX + widthOffset, currentY + heightOffset ), context.
feature(), pointRenderContext );
3922 for (
double currentX = -width; currentX <= width * 2.0; currentX += width )
3924 for (
double currentY = -height / 2.0; currentY <= height * 2.0; currentY += height )
3926 mMarkerSymbol->renderPoint( QPointF( currentX + widthOffset + displacementPixelX, currentY + heightOffset ), context.
feature(), pointRenderContext );
3930 for (
double currentX = -width / 2.0; currentX <= width * 2.0; currentX += width )
3932 for (
double currentY = -height; currentY <= height * 2.0; currentY += height / 2.0 )
3934 mMarkerSymbol->renderPoint( QPointF( currentX + widthOffset + ( std::fmod( currentY, height ) != 0 ? displacementPixelX : 0 ), currentY + heightOffset - displacementPixelY ), context.feature(), pointRenderContext );
3943 QImage transparentImage = patternImage.copy();
3945 brush.setTextureImage( transparentImage );
3949 brush.setTextureImage( patternImage );
3951 QTransform brushTransform;
3952 brush.setTransform( brushTransform );
3972 if ( !mRenderUsingMarkers )
4017 if ( !useSelectedColor && !mRenderUsingMarkers )
4067 const double widthOffset = std::fmod(
4079 const double heightOffset = std::fmod(
4105 p->setPen( QPen( Qt::NoPen ) );
4127 std::unique_ptr< QgsPolygon > shapePolygon;
4128 std::unique_ptr< QgsGeometryEngine > shapeEngine;
4135 shapePolygon = std::make_unique< QgsPolygon >();
4137 shapePolygon->setExteriorRing( fromPolygon.release() );
4140 for (
const QPolygonF &ring : *rings )
4143 shapePolygon->addInteriorRing( fromRing.release() );
4147 shapeEngine->prepareGeometry();
4154 path.addPolygon( points );
4157 for (
const QPolygonF &ring : *rings )
4159 path.addPolygon( ring );
4162 p->setClipPath( path, Qt::IntersectClip );
4168 const QRectF boundingRect = points.boundingRect();
4170 QTransform invertedRotateTransform;
4178 QTransform transform;
4179 if ( applyBrushTransform )
4182 transform.translate( -boundingRect.center().x(),
4183 -boundingRect.center().y() );
4184 transform.rotate( -
angle );
4185 transform.translate( boundingRect.center().x(),
4186 boundingRect.center().y() );
4191 transform.rotate( -
angle );
4194 const QRectF transformedBounds = transform.map( points ).boundingRect();
4195 left = transformedBounds.left() - 2 * width;
4196 top = transformedBounds.top() - 2 * height;
4197 right = transformedBounds.right() + 2 * width;
4198 bottom = transformedBounds.bottom() + 2 * height;
4199 invertedRotateTransform = transform.inverted();
4201 if ( !applyBrushTransform )
4203 left -= transformedBounds.left() - ( width * std::floor( transformedBounds.left() / width ) );
4204 top -= transformedBounds.top() - ( height * std::floor( transformedBounds.top() / height ) );
4209 left = boundingRect.left() - 2 * width;
4210 top = boundingRect.top() - 2 * height;
4211 right = boundingRect.right() + 2 * width;
4212 bottom = boundingRect.bottom() + 2 * height;
4214 if ( !applyBrushTransform )
4216 left -= boundingRect.left() - ( width * std::floor( boundingRect.left() / width ) );
4217 top -= boundingRect.top() - ( height * std::floor( boundingRect.top() / height ) );
4246 std::random_device rd;
4247 std::mt19937 mt(
seed == 0 ? rd() :
seed );
4248 std::uniform_real_distribution<> uniformDist( 0, 1 );
4254 const bool needsExpressionContext =
mMarkerSymbol->hasDataDefinedProperties();
4262 bool alternateColumn =
false;
4263 int currentCol = -3;
4264 for (
double currentX = left; currentX <= right; currentX += width, alternateColumn = !alternateColumn )
4269 if ( needsExpressionContext )
4272 bool alternateRow =
false;
4273 const double columnX = currentX + widthOffset;
4274 int currentRow = -3;
4275 for (
double currentY = top; currentY <= bottom; currentY += height, alternateRow = !alternateRow )
4280 double y = currentY + heightOffset;
4283 x += displacementPixelX;
4285 if ( !alternateColumn )
4286 y -= displacementPixelY;
4292 invertedRotateTransform.map( xx, yy, &x, &y );
4295 if ( useRandomShift )
4297 x += ( 2 * uniformDist( mt ) - 1 ) * maxRandomDeviationPixelX;
4298 y += ( 2 * uniformDist( mt ) - 1 ) * maxRandomDeviationPixelY;
4301 if ( needsExpressionContext )
4309 bool renderPoint =
true;
4317 renderPoint = shapeEngine->intersects( &p );
4329 renderPoint = shapeEngine->intersects( markerBounds.
constGet() );
4355 map.insert( QStringLiteral(
"distance_x" ), QString::number(
mDistanceX ) );
4356 map.insert( QStringLiteral(
"distance_y" ), QString::number(
mDistanceY ) );
4357 map.insert( QStringLiteral(
"displacement_x" ), QString::number(
mDisplacementX ) );
4358 map.insert( QStringLiteral(
"displacement_y" ), QString::number(
mDisplacementY ) );
4359 map.insert( QStringLiteral(
"offset_x" ), QString::number(
mOffsetX ) );
4360 map.insert( QStringLiteral(
"offset_y" ), QString::number(
mOffsetY ) );
4376 map.insert( QStringLiteral(
"random_deviation_x" ), QString::number(
mRandomDeviationX ) );
4377 map.insert( QStringLiteral(
"random_deviation_y" ), QString::number(
mRandomDeviationY ) );
4382 map.insert( QStringLiteral(
"seed" ), QString::number(
mSeed ) );
4383 map.insert( QStringLiteral(
"angle" ),
mAngle );
4402 for (
int symbolLayerIdx = 0; symbolLayerIdx <
mMarkerSymbol->symbolLayerCount(); symbolLayerIdx++ )
4404 QDomElement symbolizerElem = doc.createElement( QStringLiteral(
"se:PolygonSymbolizer" ) );
4405 if ( !props.value( QStringLiteral(
"uom" ), QString() ).toString().isEmpty() )
4406 symbolizerElem.setAttribute( QStringLiteral(
"uom" ), props.value( QStringLiteral(
"uom" ), QString() ).toString() );
4407 element.appendChild( symbolizerElem );
4412 QDomElement fillElem = doc.createElement( QStringLiteral(
"se:Fill" ) );
4413 symbolizerElem.appendChild( fillElem );
4415 QDomElement graphicFillElem = doc.createElement( QStringLiteral(
"se:GraphicFill" ) );
4416 fillElem.appendChild( graphicFillElem );
4423 bool exportOk {
false };
4427 if ( ! image.isNull() )
4429 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
4430 graphicFillElem.appendChild( graphicElem );
4431 const QFileInfo info { context.exportFilePath() };
4432 QString pngPath { info.completeSuffix().isEmpty() ? context.exportFilePath() : context.exportFilePath().chopped( info.completeSuffix().length() ).append( QStringLiteral(
"png" ) ) };
4434 image.save( pngPath );
4453 symbolizerElem.appendChild( graphicMarginElem );
4457 markerLayer->writeSldMarker( doc, graphicFillElem, props );
4461 QString errorMsg = QStringLiteral(
"QgsMarkerSymbolLayer expected, %1 found. Skip it." ).arg( layer->
layerType() );
4462 graphicFillElem.appendChild( doc.createComment( errorMsg ) );
4466 QString errorMsg = QStringLiteral(
"Missing point pattern symbol layer. Skip it." );
4467 graphicFillElem.appendChild( doc.createComment( errorMsg ) );
4476 double angleRads { qDegreesToRadians(
mAngle ) };
4485 if ( displacementXPx != 0 )
4490 if ( displacementYPx != 0 )
4497 QPixmap pixmap( size );
4498 pixmap.fill( Qt::transparent );
4500 painter.begin( &pixmap );
4501 painter.setRenderHint( QPainter::Antialiasing );
4509 std::unique_ptr< QgsPointPatternFillSymbolLayer > layerClone(
clone() );
4511 layerClone->setAngle( qRadiansToDegrees( angleRads ) );
4514 layerClone->setMaximumRandomDeviationX( 0 );
4515 layerClone->setMaximumRandomDeviationY( 0 );
4517 layerClone->drawPreviewIcon( symbolContext, pixmap.size() );
4519 return pixmap.toImage();
4527 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
4528 if ( fillElem.isNull() )
4531 QDomElement graphicFillElem = fillElem.firstChildElement( QStringLiteral(
"GraphicFill" ) );
4532 if ( graphicFillElem.isNull() )
4535 QDomElement graphicElem = graphicFillElem.firstChildElement( QStringLiteral(
"Graphic" ) );
4536 if ( graphicElem.isNull() )
4540 if ( !simpleMarkerSl )
4545 layers.append( simpleMarkerSl );
4547 std::unique_ptr< QgsMarkerSymbol > marker = std::make_unique< QgsMarkerSymbol >( layers );
4550 const double markerSize { marker->size() };
4552 std::unique_ptr< QgsPointPatternFillSymbolLayer > pointPatternFillSl = std::make_unique< QgsPointPatternFillSymbolLayer >();
4553 pointPatternFillSl->setSubSymbol( marker.release() );
4558 auto distanceParser = [ & ](
const QStringList & values )
4560 switch ( values.count( ) )
4565 const double v { values.at( 0 ).toDouble( &ok ) };
4568 pointPatternFillSl->setDistanceX( v * 2 + markerSize );
4569 pointPatternFillSl->setDistanceY( v * 2 + markerSize );
4576 const double vX { values.at( 1 ).toDouble( &ok ) };
4579 pointPatternFillSl->setDistanceX( vX * 2 + markerSize );
4581 const double vY { values.at( 0 ).toDouble( &ok ) };
4584 pointPatternFillSl->setDistanceY( vY * 2 + markerSize );
4591 const double vX { values.at( 1 ).toDouble( &ok ) };
4594 pointPatternFillSl->setDistanceX( vX * 2 + markerSize );
4596 const double vYt { values.at( 0 ).toDouble( &ok ) };
4599 const double vYb { values.at( 2 ).toDouble( &ok ) };
4602 pointPatternFillSl->setDistanceY( ( vYt + vYb ) + markerSize );
4610 const double vYt { values.at( 0 ).toDouble( &ok ) };
4613 const double vYb { values.at( 2 ).toDouble( &ok ) };
4616 pointPatternFillSl->setDistanceY( ( vYt + vYb ) + markerSize );
4619 const double vXr { values.at( 1 ).toDouble( &ok ) };
4622 const double vXl { values.at( 3 ).toDouble( &ok ) };
4625 pointPatternFillSl->setDistanceX( ( vXr + vXl ) + markerSize );
4636 bool distanceFromVendorOption {
false };
4638 for ( QgsStringMap::iterator it = vendorOptions.begin(); it != vendorOptions.end(); ++it )
4641 if ( it.key() == QLatin1String(
"distance" ) )
4643 distanceParser( it.value().split(
',' ) );
4644 distanceFromVendorOption =
true;
4647 else if ( it.key() == QLatin1String(
"graphic-margin" ) )
4649 distanceParser( it.value().split(
' ' ) );
4650 distanceFromVendorOption =
true;
4655 if ( ! distanceFromVendorOption && ! graphicFillElem.elementsByTagName( QStringLiteral(
"Size" ) ).isEmpty() )
4657 const QDomElement sizeElement { graphicFillElem.elementsByTagName( QStringLiteral(
"Size" ) ).at( 0 ).toElement() };
4659 const double size { sizeElement.text().toDouble( &ok ) };
4662 pointPatternFillSl->setDistanceX( size );
4663 pointPatternFillSl->setDistanceY( size );
4667 return pointPatternFillSl.release();
4749 attributes.unite(
mMarkerSymbol->usedAttributes( context ) );
4787 std::unique_ptr< QgsCentroidFillSymbolLayer > sl = std::make_unique< QgsCentroidFillSymbolLayer >();
4789 if (
properties.contains( QStringLiteral(
"point_on_surface" ) ) )
4790 sl->setPointOnSurface(
properties[QStringLiteral(
"point_on_surface" )].toInt() != 0 );
4791 if (
properties.contains( QStringLiteral(
"point_on_all_parts" ) ) )
4792 sl->setPointOnAllParts(
properties[QStringLiteral(
"point_on_all_parts" )].toInt() != 0 );
4793 if (
properties.contains( QStringLiteral(
"clip_points" ) ) )
4794 sl->setClipPoints(
properties[QStringLiteral(
"clip_points" )].toInt() != 0 );
4795 if (
properties.contains( QStringLiteral(
"clip_on_current_part_only" ) ) )
4796 sl->setClipOnCurrentPartOnly(
properties[QStringLiteral(
"clip_on_current_part_only" )].toInt() != 0 );
4798 sl->restoreOldDataDefinedProperties(
properties );
4800 return sl.release();
4805 return QStringLiteral(
"CentroidFill" );
4833 part.exterior = points;
4835 part.rings = *rings;
4843 mCurrentParts << part;
4848 const double prevOpacity =
mMarker->opacity();
4852 mMarker->setOpacity( prevOpacity );
4861 mCurrentParts.clear();
4868 const double prevOpacity =
mMarker->opacity();
4874 mMarker->setOpacity( prevOpacity );
4879void QgsCentroidFillSymbolLayer::render(
QgsRenderContext &context,
const QVector<QgsCentroidFillSymbolLayer::Part> &parts,
const QgsFeature &feature,
bool selected )
4888 QVector< QgsGeometry > geometryParts;
4889 geometryParts.reserve( parts.size() );
4890 QPainterPath globalPath;
4893 int maxAreaPartIdx = 0;
4895 for (
int i = 0; i < parts.size(); i++ )
4897 const Part part = parts[i];
4900 if ( !geom.
isNull() && !part.rings.empty() )
4902 QgsPolygon *poly = qgsgeometry_cast< QgsPolygon * >( geom.
get() );
4906 int area = poly->
area();
4908 if ( area > maxArea )
4918 globalPath.addPolygon( part.exterior );
4919 for (
const QPolygonF &ring : part.rings )
4921 globalPath.addPolygon( ring );
4926 for (
int i = 0; i < parts.size(); i++ )
4931 const Part part = parts[i];
4939 path.addPolygon( part.exterior );
4940 for (
const QPolygonF &ring : part.rings )
4942 path.addPolygon( ring );
4951 context.
painter()->setClipPath( path );
4958 mMarker->renderPoint( centroid, feature.
isValid() ? &feature : nullptr, context, -1, selected );
4971 map[QStringLiteral(
"point_on_surface" )] = QString::number(
mPointOnSurface );
4972 map[QStringLiteral(
"point_on_all_parts" )] = QString::number(
mPointOnAllParts );
4973 map[QStringLiteral(
"clip_points" )] = QString::number(
mClipPoints );
4980 std::unique_ptr< QgsCentroidFillSymbolLayer > x = std::make_unique< QgsCentroidFillSymbolLayer >();
4983 x->setSubSymbol(
mMarker->clone() );
4998 mMarker->toSld( doc, element, props );
5009 std::unique_ptr< QgsMarkerSymbol > marker(
new QgsMarkerSymbol( layers ) );
5011 std::unique_ptr< QgsCentroidFillSymbolLayer > sl = std::make_unique< QgsCentroidFillSymbolLayer >();
5012 sl->setSubSymbol( marker.release() );
5013 sl->setPointOnAllParts(
false );
5014 return sl.release();
5041 attributes.unite(
mMarker->usedAttributes( context ) );
5064 mMarker->setOutputUnit( unit );
5081 return mMarker->usesMapUnits();
5090 mMarker->setMapUnitScale( scale );
5098 return mMarker->mapUnitScale();
5108 , mImageFilePath( imageFilePath )
5125 if (
properties.contains( QStringLiteral(
"imageFile" ) ) )
5127 imagePath =
properties[QStringLiteral(
"imageFile" )].toString();
5129 if (
properties.contains( QStringLiteral(
"coordinate_mode" ) ) )
5133 if (
properties.contains( QStringLiteral(
"alpha" ) ) )
5135 alpha =
properties[QStringLiteral(
"alpha" )].toDouble();
5137 if (
properties.contains( QStringLiteral(
"offset" ) ) )
5141 if (
properties.contains( QStringLiteral(
"angle" ) ) )
5145 if (
properties.contains( QStringLiteral(
"width" ) ) )
5149 std::unique_ptr< QgsRasterFillSymbolLayer > symbolLayer = std::make_unique< QgsRasterFillSymbolLayer >( imagePath );
5150 symbolLayer->setCoordinateMode( mode );
5151 symbolLayer->setOpacity( alpha );
5152 symbolLayer->setOffset(
offset );
5153 symbolLayer->setAngle(
angle );
5154 symbolLayer->setWidth(
width );
5155 if (
properties.contains( QStringLiteral(
"offset_unit" ) ) )
5159 if (
properties.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
5163 if (
properties.contains( QStringLiteral(
"width_unit" ) ) )
5167 if (
properties.contains( QStringLiteral(
"width_map_unit_scale" ) ) )
5172 if (
properties.contains( QStringLiteral(
"height" ) ) )
5174 symbolLayer->setHeight(
properties[QStringLiteral(
"height" )].toDouble() );
5177 symbolLayer->restoreOldDataDefinedProperties(
properties );
5179 return symbolLayer.release();
5184 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
5185 if ( fillElem.isNull() )
5188 QDomElement graphicFillElem = fillElem.firstChildElement( QStringLiteral(
"GraphicFill" ) );
5189 if ( graphicFillElem.isNull() )
5192 QDomElement graphicElem = graphicFillElem.firstChildElement( QStringLiteral(
"Graphic" ) );
5193 if ( graphicElem.isNull() )
5196 QString path, mimeType;
5204 if ( ! QFile::exists( path ) )
5209 std::unique_ptr< QgsRasterFillSymbolLayer> sl = std::make_unique< QgsRasterFillSymbolLayer>( path );
5211 return sl.release();
5216 QVariantMap::iterator it =
properties.find( QStringLiteral(
"imageFile" ) );
5220 it.value() = pathResolver.
writePath( it.value().toString() );
5222 it.value() = pathResolver.
readPath( it.value().toString() );
5234 return QStringLiteral(
"RasterFill" );
5250 QPointF
offset = mOffset;
5268 QRectF boundingRect = points.boundingRect();
5269 mBrush.setTransform(
mBrush.transform().translate( boundingRect.left() -
mBrush.transform().dx(),
5270 boundingRect.top() -
mBrush.transform().dy() ) );
5282 applyPattern(
mBrush, mImageFilePath, mWidth, mHeight, mOpacity * context.
opacity(), context );
5293 map[QStringLiteral(
"imageFile" )] = mImageFilePath;
5294 map[QStringLiteral(
"coordinate_mode" )] = QString::number(
static_cast< int >( mCoordinateMode ) );
5295 map[QStringLiteral(
"alpha" )] = QString::number( mOpacity );
5299 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
5301 map[QStringLiteral(
"width" )] = QString::number( mWidth );
5302 map[QStringLiteral(
"height" )] = QString::number( mHeight );
5311 std::unique_ptr< QgsRasterFillSymbolLayer > sl = std::make_unique< QgsRasterFillSymbolLayer >( mImageFilePath );
5312 sl->setCoordinateMode( mCoordinateMode );
5313 sl->setOpacity( mOpacity );
5314 sl->setOffset( mOffset );
5315 sl->setOffsetUnit( mOffsetUnit );
5316 sl->setOffsetMapUnitScale( mOffsetMapUnitScale );
5318 sl->setWidth( mWidth );
5319 sl->setHeight( mHeight );
5320 sl->setSizeUnit( mSizeUnit );
5321 sl->setSizeMapUnitScale( mSizeMapUnitScale );
5325 return sl.release();
5330 return context.
convertToPainterUnits( std::max( std::fabs( mOffset.x() ), std::fabs( mOffset.y() ) ), mOffsetUnit, mOffsetMapUnitScale );
5353 mImageFilePath = imagePath;
5358 mCoordinateMode = mode;
5377 if ( !hasWidthExpression && !hasHeightExpression && !hasAngleExpression && !hasOpacityExpression && !hasFileExpression )
5383 if ( hasAngleExpression )
5391 if ( !hasWidthExpression && !hasHeightExpression && !hasOpacityExpression && !hasFileExpression )
5396 double width = mWidth;
5397 if ( hasWidthExpression )
5403 if ( hasHeightExpression )
5409 if ( hasOpacityExpression )
5414 QString file = mImageFilePath;
5415 if ( hasFileExpression )
5428void QgsRasterFillSymbolLayer::applyPattern( QBrush &brush,
const QString &imageFilePath,
const double width,
const double height,
const double alpha,
const QgsSymbolRenderContext &context )
5430 double imageWidth = 0;
5431 double imageHeight = 0;
5446 if ( originalSize.isEmpty() )
5449 imageWidth = (
width * originalSize.width() ) / 100.0;
5452 if (
static_cast< int >( imageWidth ) < 1 || 10000.0 < imageWidth )
5465 if ( !originalSize.isValid() )
5468 if ( originalSize.isEmpty() )
5471 imageHeight = (
height * originalSize.height() ) / 100.0;
5474 if (
static_cast< int >( imageHeight ) < 1 || 10000.0 < imageHeight )
5479 if (
width == 0 && imageHeight > 0 )
5481 if ( !originalSize.isValid() )
5484 imageWidth = imageHeight * originalSize.width() / originalSize.height();
5486 else if (
height == 0 && imageWidth > 0 )
5488 if ( !originalSize.isValid() )
5491 imageHeight = imageWidth * originalSize.height() / originalSize.width();
5493 if ( imageWidth == 0 || imageHeight == 0 )
5495 if ( !originalSize.isValid() )
5498 imageWidth = originalSize.width();
5499 imageHeight = originalSize.height();
5507 brush.setTextureImage( img );
5516 : mCountMethod( method )
5517 , mPointCount( pointCount )
5518 , mDensityArea( densityArea )
5529 const int pointCount =
properties.value( QStringLiteral(
"point_count" ), QStringLiteral(
"10" ) ).toInt();
5530 const double densityArea =
properties.value( QStringLiteral(
"density_area" ), QStringLiteral(
"250.0" ) ).toDouble();
5532 unsigned long seed = 0;
5533 if (
properties.contains( QStringLiteral(
"seed" ) ) )
5539 std::random_device rd;
5540 std::mt19937 mt(
seed == 0 ? rd() :
seed );
5541 std::uniform_int_distribution<> uniformDist( 1, 999999999 );
5542 seed = uniformDist( mt );
5547 if (
properties.contains( QStringLiteral(
"density_area_unit" ) ) )
5549 if (
properties.contains( QStringLiteral(
"density_area_unit_scale" ) ) )
5552 if (
properties.contains( QStringLiteral(
"clip_points" ) ) )
5554 sl->setClipPoints(
properties[QStringLiteral(
"clip_points" )].toInt() );
5557 return sl.release();
5562 return QStringLiteral(
"RandomMarkerFill" );
5567 mMarker->setColor(
color );
5573 return mMarker ? mMarker->color() :
mColor;
5590 part.exterior = points;
5592 part.rings = *rings;
5594 if ( mRenderingFeature )
5598 mFeatureSymbolOpacity = context.
opacity();
5599 mCurrentParts << part;
5604 const double prevOpacity = mMarker->opacity();
5605 mMarker->setOpacity( mMarker->opacity() * context.
opacity() );
5608 mMarker->setOpacity( prevOpacity );
5612void QgsRandomMarkerFillSymbolLayer::render(
QgsRenderContext &context,
const QVector<QgsRandomMarkerFillSymbolLayer::Part> &parts,
const QgsFeature &feature,
bool selected )
5621 QVector< QgsGeometry > geometryParts;
5622 geometryParts.reserve( parts.size() );
5625 for (
const Part &part : parts )
5628 if ( !geom.
isNull() && !part.rings.empty() )
5630 QgsPolygon *poly = qgsgeometry_cast< QgsPolygon * >( geom.
get() );
5631 for (
const QPolygonF &ring : part.rings )
5639 geom = geom.
buffer( 0, 0 );
5641 geometryParts << geom;
5645 path.addPolygon( part.exterior );
5646 for (
const QPolygonF &ring : part.rings )
5648 path.addPolygon( ring );
5658 context.
painter()->setClipPath( path );
5662 int count = mPointCount;
5669 switch ( mCountMethod )
5681 count = std::max( 0.0, std::ceil( count * ( geom.
area() /
densityArea ) ) );
5688 unsigned long seed = mSeed;
5699 std::sort( randomPoints.begin(), randomPoints.end(), [](
const QgsPointXY & a,
const QgsPointXY & b )->bool
5701 return a.y() < b.y();
5707 const bool needsExpressionContext = mMarker->hasDataDefinedProperties();
5712 for (
const QgsPointXY &p : std::as_const( randomPoints ) )
5714 if ( needsExpressionContext )
5716 mMarker->renderPoint( QPointF( p.x(), p.y() ), feature.
isValid() ? &feature : nullptr, context, -1, selected );
5730 map.insert( QStringLiteral(
"count_method" ), QString::number(
static_cast< int >( mCountMethod ) ) );
5731 map.insert( QStringLiteral(
"point_count" ), QString::number( mPointCount ) );
5732 map.insert( QStringLiteral(
"density_area" ), QString::number( mDensityArea ) );
5735 map.insert( QStringLiteral(
"seed" ), QString::number( mSeed ) );
5736 map.insert( QStringLiteral(
"clip_points" ), QString::number( mClipPoints ) );
5742 std::unique_ptr< QgsRandomMarkerFillSymbolLayer > res = std::make_unique< QgsRandomMarkerFillSymbolLayer >( mPointCount, mCountMethod, mDensityArea, mSeed );
5745 res->setDensityAreaUnit( mDensityAreaUnit );
5746 res->setDensityAreaUnitScale( mDensityAreaUnitScale );
5747 res->mClipPoints = mClipPoints;
5748 res->setSubSymbol( mMarker->clone() );
5751 return res.release();
5761 return mMarker.get();
5773 mColor = mMarker->color();
5782 attributes.unite( mMarker->usedAttributes( context ) );
5791 if ( mMarker && mMarker->hasDataDefinedProperties() )
5828 return mCountMethod;
5833 mCountMethod = method;
5838 return mDensityArea;
5843 mDensityArea = area;
5850 mRenderingFeature =
true;
5851 mCurrentParts.clear();
5856 mRenderingFeature =
false;
5858 const double prevOpacity = mMarker->opacity();
5859 mMarker->setOpacity( mMarker->opacity() * mFeatureSymbolOpacity );
5861 render( context, mCurrentParts, feature,
false );
5863 mFeatureSymbolOpacity = 1;
5864 mMarker->setOpacity( prevOpacity );
5872 mDensityAreaUnit = unit;
5875 mMarker->setOutputUnit( unit );
5883 return mMarker->outputUnit();
5892 return mMarker->usesMapUnits();
5901 mMarker->setMapUnitScale( scale );
5909 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.
@ IsSymbolLayerSubSymbol
Symbol is being rendered as a sub-symbol of a QgsSymbolLayer.
LineClipMode
Line clipping modes.
@ NoClipping
Lines are not clipped, will extend to shape's bounding box.
@ ClipPainterOnly
Applying clipping on the painter only (i.e. line endpoints will coincide with polygon bounding box,...
@ ClipToIntersection
Clip lines to intersection with polygon shape (slower) (i.e. line endpoints will coincide with polygo...
GradientColorSource
Gradient color sources.
@ ColorRamp
Gradient color ramp.
@ SimpleTwoColor
Simple two color gradient.
@ CanCalculateMaskGeometryPerFeature
If present, indicates that mask geometry can safely be calculated per feature for the symbol layer....
GradientSpread
Gradient spread options, which control how gradients are rendered outside of their start and end poin...
@ Reflect
Reflect gradient.
@ Pad
Pad out gradient using colors at endpoint of gradient.
@ Png
Export complex styles to separate PNG files for better compatibility with OGC servers.
PointCountMethod
Methods which define the number of points randomly filling a polygon.
@ Absolute
The point count is used as an absolute count of markers.
@ DensityBased
The point count is part of a marker density count.
QFlags< SymbolLayerFlag > SymbolLayerFlags
Symbol layer flags.
RenderUnit
Rendering size units.
@ Percentage
Percentage of another measurement (e.g., canvas size, feature size)
@ Unknown
Mixed or unknown units.
@ MetersInMapUnits
Meters value as Map units.
@ RenderingSubSymbol
Set whenever a sub-symbol of a parent symbol is currently being rendered. Can be used during symbol a...
@ RenderSymbolPreview
The render is for a symbol preview only and map based properties may not be available,...
@ RenderMapTile
Draw map such that there are no problems between adjacent tiles.
@ HighQualityImageTransforms
Enable high quality image transformations, which results in better appearance of scaled or rotated ra...
@ RenderBlocking
Render and load remote sources in the same thread to ensure rendering remote sources (svg and images)...
GradientType
Gradient types.
@ Conical
Conical (polar) gradient.
@ Radial
Radial (circular) gradient.
QFlags< SymbolRenderHint > SymbolRenderHints
Symbol render hints.
SymbolCoordinateReference
Symbol coordinate reference modes.
@ Feature
Relative to feature/shape being rendered.
@ Viewport
Relative to the whole viewport/output device.
QColor valueAsColor(int key, const QgsExpressionContext &context, const QColor &defaultColor=QColor(), bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a color.
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...
A fill symbol layer which renders a marker symbol at the centroid of a polygon geometry.
static QgsSymbolLayer * createFromSld(QDomElement &element)
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
QgsSymbol * subSymbol() override
Returns the symbol's sub symbol, if present.
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
void setMapUnitScale(const QgsMapUnitScale &scale) override
bool canCauseArtifactsBetweenAdjacentTiles() const override
Returns true if the symbol layer rendering can cause visible artifacts across a single feature when t...
bool 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.
bool setSubSymbol(QgsSymbol *symbol) FINAL
Sets layer's subsymbol. takes ownership of the passed symbol.
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 QColor colorFromString(const QString &string)
Decodes a string into a color value.
static QString colorToString(const QColor &color)
Encodes a color into a string value.
static QgsColorRamp * create(const QVariantMap &properties=QVariantMap())
Creates the symbol layer.
static QString typeString()
Returns the string identifier for QgsCptCityColorRamp.
double area() const override
Returns the planar, 2-dimensional area of the geometry.
Exports QGIS layers to the DXF format.
static double mapUnitScaleFactor(double scale, Qgis::RenderUnit symbolUnits, Qgis::DistanceUnit mapUnits, double mapUnitsPerPixel=1.0)
Returns scale factor for conversion to map units.
Qgis::DistanceUnit mapUnits() const
Retrieve map units.
double symbologyScale() const
Returns the reference scale for output.
RAII class to pop scope from an expression context on destruction.
Single scope for storing variables and functions for use within a QgsExpressionContext.
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
static const QString EXPR_GEOMETRY_POINT_NUM
Inbuilt variable name for point number variable.
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for the context.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
bool isValid() const
Returns the validity of this feature.
bool isCanceled() const
Tells whether the operation has been canceled already.
static QString uniquePath(const QString &path)
Creates a unique file path name from a desired path by appending _<n> (where <n> is an integer number...
void _renderPolygon(QPainter *p, const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context)
Default method to render polygon.
double angle() const
Returns the rotation angle of the fill symbol, in degrees clockwise.
A geometry is the spatial representation of a feature.
QVector< QgsPointXY > randomPointsInPolygon(int count, const std::function< bool(const QgsPointXY &) > &acceptPoint, unsigned long seed=0, QgsFeedback *feedback=nullptr, int maxTriesPerPoint=0) const
Returns a list of count random points generated inside a (multi)polygon geometry (if acceptPoint is s...
static QgsGeometry fromRect(const QgsRectangle &rect)
Creates a new geometry from a QgsRectangle.
static QgsGeometry fromQPolygonF(const QPolygonF &polygon)
Construct geometry from a QPolygonF.
QgsAbstractGeometry * get()
Returns a modifiable (non-const) reference to the underlying abstract geometry primitive.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
bool contains(const QgsPointXY *p) const
Returns true if the geometry contains the point p.
bool isGeosValid(Qgis::GeometryValidityFlags flags=Qgis::GeometryValidityFlags()) const
Checks validity of the geometry using GEOS.
double area() const
Returns the planar, 2-dimensional area of the geometry.
QgsGeometry buffer(double distance, int segments) const
Returns a buffer region around this geometry having the given width and with a specified number of se...
static QgsGeometry unaryUnion(const QVector< QgsGeometry > &geometries, const QgsGeometryParameters ¶meters=QgsGeometryParameters())
Compute the unary union on a list of geometries.
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometry *geometry, double precision=0.0, Qgis::GeosCreationFlags flags=Qgis::GeosCreationFlag::SkipEmptyInteriorRings)
Creates and returns a new geometry engine representing the specified geometry using precision on a gr...
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.
A fill symbol layer which draws a smooth color gradient over a polygon.
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.
Qgis::SymbolLayerFlags flags() const override
Returns flags which control the symbol layer's behavior.
QString layerType() const override
Returns a string that represents this layer type.
Qgis::RenderUnit mOffsetUnit
Qgis::GradientType gradientType() const
Returns the type of gradient, e.g., linear or radial.
QPointF referencePoint2() const
Returns the end point of gradient fill, in the range [0,0] - [1,1].
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.
static std::unique_ptr< QgsLineString > fromQPolygonF(const QPolygonF &polygon)
Returns a new linestring from a QPolygonF polygon input.
QPolygonF asQPolygonF() const override
Returns a QPolygonF representing the points.
A line symbol type, for rendering LineString and MultiLineString geometries.
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)
bool mMarkerSymbolRenderStarted
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 final
Returns the calculated value of the property with the specified key from within the collection.
bool isActive(int key) const final
Returns true if the collection contains an active property with the specified key.
static QVariantMap propertyMapToVariantMap(const QMap< QString, QgsProperty > &propertyMap)
Convert a map of QgsProperty to a map of QVariant This is useful to save a map of properties.
static QMap< QString, QgsProperty > variantMapToPropertyMap(const QVariantMap &variantMap)
Convert a map of QVariant to a map of QgsProperty This is useful to restore a map of properties.
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 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.
bool setSubSymbol(QgsSymbol *symbol) FINAL
Sets layer's subsymbol. takes ownership of the passed symbol.
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 ...
Qgis::SymbolLayerFlags flags() const override
Returns flags which control the symbol layer's behavior.
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
static QgsSymbolLayer * createFromSld(QDomElement &element)
Creates a new QgsRasterFillSymbolLayer from a SLD element.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsRasterFillSymbolLayer from a properties map.
QString layerType() const override
Returns a string that represents this layer type.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QgsRasterFillSymbolLayer(const QString &imageFilePath=QString())
Constructor for QgsRasterFillSymbolLayer, using a raster fill from the specified imageFilePath.
double opacity() const
Returns the opacity for the raster image used in the fill.
~QgsRasterFillSymbolLayer() override
void setOpacity(double opacity)
Sets the opacity for the raster image used in the fill.
QColor color() const override
Returns the "representative" color of the symbol layer.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
QString imageFilePath() const
The path to the raster image used for the fill.
void setImageFilePath(const QString &imagePath)
Sets the path to the raster image used for the fill.
double height() const
Returns the height used for scaling the image used in the fill.
static void resolvePaths(QVariantMap &properties, const QgsPathResolver &pathResolver, bool saving)
Turns relative paths in properties map to absolute when reading and vice versa when writing.
QPointF offset() const
Returns the offset for the fill.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer's subsymbol. takes ownership of the passed symbol.
QgsRasterFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
bool applyBrushTransformFromContext(QgsSymbolRenderContext *context=nullptr) const override
Returns true if the image brush should be transformed using the render context's texture origin.
void setCoordinateMode(Qgis::SymbolCoordinateReference mode)
Set the coordinate mode for fill.
A rectangle specified with double values.
Contains information about the context of a rendering operation.
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.
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.
Qgis::SymbolLayerFlags flags() const override
Returns flags which control the symbol layer's behavior.
QString layerType() const override
Returns a string that represents this layer type.
Qgis::GradientColorSource colorType() const
Returns the color mode used for the shapeburst fill.
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
void setColorRamp(QgsColorRamp *ramp)
Sets the color ramp used to draw the shapeburst fill.
Renders polygons using a single fill and stroke color.
QgsSimpleFillSymbolLayer(const QColor &color=DEFAULT_SIMPLEFILL_COLOR, Qt::BrushStyle style=DEFAULT_SIMPLEFILL_STYLE, const QColor &strokeColor=DEFAULT_SIMPLEFILL_BORDERCOLOR, Qt::PenStyle strokeStyle=DEFAULT_SIMPLEFILL_BORDERSTYLE, double strokeWidth=DEFAULT_SIMPLEFILL_BORDERWIDTH, Qt::PenJoinStyle penJoinStyle=DEFAULT_SIMPLEFILL_JOINSTYLE)
double dxfWidth(const QgsDxfExport &e, QgsSymbolRenderContext &context) const override
Gets line width.
Qt::PenJoinStyle penJoinStyle() const
QColor strokeColor() const override
Returns the stroke color for the symbol layer.
QColor dxfBrushColor(QgsSymbolRenderContext &context) const override
Gets brush/fill color.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
Qt::BrushStyle dxfBrushStyle() const override
Gets brush/fill style.
QString ogrFeatureStyle(double mmScaleFactor, double mapUnitScaleFactor) const override
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
Qgis::SymbolLayerFlags flags() const override
Returns flags which control the symbol layer's behavior.
Qgis::RenderUnit mOffsetUnit
~QgsSimpleFillSymbolLayer() override
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.
Contains utility functions for working with symbols and symbol layers.
static bool rotationFromSldElement(QDomElement &element, QString &rotationFunc)
static Qgis::MarkerClipMode decodeMarkerClipMode(const QString &string, bool *ok=nullptr)
Decodes a string representing a marker clip mode.
static QString encodePenStyle(Qt::PenStyle style)
static Qt::PenJoinStyle decodePenJoinStyle(const QString &str)
static QString encodeMapUnitScale(const QgsMapUnitScale &mapUnitScale)
static QgsStringMap evaluatePropertiesMap(const QMap< QString, QgsProperty > &propertiesMap, const QgsExpressionContext &context)
Evaluates a map of properties using the given context and returns a variant map with evaluated expres...
static bool displacementFromSldElement(QDomElement &element, QPointF &offset)
static QPointF polygonCentroid(const QPolygonF &points)
Calculate the centroid point of a QPolygonF.
static QString encodeBrushStyle(Qt::BrushStyle style)
static QString svgSymbolPathToName(const QString &path, const QgsPathResolver &pathResolver)
Determines an SVG symbol's name from its path.
static void externalGraphicToSld(QDomDocument &doc, QDomElement &element, const QString &path, const QString &mime, const QColor &color, double size=-1)
static QPointF polygonPointOnSurface(const QPolygonF &points, const QVector< QPolygonF > *rings=nullptr)
Calculate a point on the surface of a QPolygonF.
static QPointF toPoint(const QVariant &value, bool *ok=nullptr)
Converts a value to a point.
static void multiplyImageOpacity(QImage *image, qreal opacity)
Multiplies opacity of image pixel values with a (global) transparency value.
static QgsMapUnitScale decodeMapUnitScale(const QString &str)
static double rescaleUom(double size, Qgis::RenderUnit unit, const QVariantMap &props)
Rescales the given size based on the uomScale found in the props, if any is found,...
static 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.
virtual bool setSubSymbol(QgsSymbol *symbol)
Sets layer's subsymbol. takes ownership of the passed symbol.
bool shouldRenderUsingSelectionColor(const QgsSymbolRenderContext &context) const
Returns true if the symbol layer should be rendered using the selection color from the render context...
Qgis::SymbolType type() const
virtual QColor fillColor() const
Returns the fill color for the symbol layer.
static const bool SELECTION_IS_OPAQUE
Whether styles for selected features ignore symbol alpha.
bool installMasks(QgsRenderContext &context, bool recursive, const QRectF &rect=QRectF())
When rendering, install masks on context painter.
void removeMasks(QgsRenderContext &context, bool recursive)
When rendering, remove previously installed masks from context painter if recursive is true masks are...
virtual QSet< QString > usedAttributes(const QgsRenderContext &context) const
Returns the set of attributes referenced by the layer.
void copyDataDefinedProperties(QgsSymbolLayer *destLayer) const
Copies all data defined properties of this layer to another symbol layer.
@ GradientType
Gradient fill type.
@ SecondaryColor
Secondary color (eg for gradient fills)
@ File
Filename, eg for svg files.
@ GradientReference2Y
Gradient reference point 2 y.
@ GradientReference1X
Gradient reference point 1 x.
@ OffsetY
Vertical offset.
@ OffsetX
Horizontal offset.
@ GradientReference1Y
Gradient reference point 1 y.
@ GradientSpread
Gradient spread mode.
@ ShapeburstMaxDistance
Shapeburst fill from edge distance.
@ StrokeStyle
Stroke style (eg solid, dashed)
@ DistanceY
Vertical distance between points.
@ DensityArea
Density area.
@ ClipPoints
Whether markers should be clipped to polygon boundaries.
@ LineClipping
Line clipping mode.
@ ShapeburstIgnoreRings
Shapeburst ignore rings.
@ ShapeburstUseWholeShape
Shapeburst use whole shape.
@ DisplacementX
Horizontal displacement.
@ CoordinateMode
Gradient coordinate mode.
@ FillStyle
Fill style (eg solid, dots)
@ GradientReference2X
Gradient reference point 2 x.
@ StrokeColor
Stroke color.
@ BlurRadius
Shapeburst blur radius.
@ MarkerClipping
Marker clipping mode.
@ RandomSeed
Random number seed.
@ LineAngle
Line angle, or angle of hash lines for hash line symbols.
@ JoinStyle
Line join style.
@ RandomOffsetY
Random offset Y.
@ DisplacementY
Vertical displacement.
@ DistanceX
Horizontal distance between points.
@ GradientReference1IsCentroid
Gradient reference point 1 is centroid.
@ StrokeWidth
Stroke width.
@ GradientReference2IsCentroid
Gradient reference point 2 is centroid.
@ LineDistance
Distance between lines, or length of lines for hash line symbols.
@ RandomOffsetX
Random offset X.
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.
virtual Qgis::SymbolLayerFlags flags() const
Returns flags which control the symbol layer's behavior.
QgsPropertyCollection mDataDefinedProperties
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the symbol layer's property collection, used for data defined overrides.
static const bool SELECT_FILL_STYLE
Whether fill styles for selected features uses symbol layer style.
virtual bool hasDataDefinedProperties() const
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
const QgsFeature * feature() const
Returns the current feature being rendered.
QgsFields fields() const
Fields of the layer.
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for data defined symbology.
bool forceVectorRendering() const
Returns true if symbol must be rendered using vector methods, and optimisations like pre-rendered ima...
qreal opacity() const
Returns the opacity for the symbol.
QgsRenderContext & renderContext()
Returns a reference to the context's render context.
Abstract base class for all rendered symbols.
QColor color() const
Returns the symbol's color.
Qgis::SymbolType type() const
Returns the symbol's type.
double interval() const
Returns the interval between individual symbols.
const QgsMapUnitScale & intervalMapUnitScale() const
Returns the map unit scale for the interval between symbols.
void setInterval(double interval)
Sets the interval between individual symbols.
Qgis::RenderUnit intervalUnit() const
Returns the units for the interval between symbols.
static Q_INVOKABLE Qgis::RenderUnit decodeRenderUnit(const QString &string, bool *ok=nullptr)
Decodes a render unit from a string.
static Q_INVOKABLE QString encodeUnit(Qgis::DistanceUnit unit)
Encodes a distance unit to a string.
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
QMap< QString, QString > QgsStringMap
#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.