46#include <QSvgRenderer>
47#include <QDomDocument>
56 Qt::PenJoinStyle penJoinStyle )
57 : mBrushStyle( style )
58 , mStrokeColor( strokeColor )
59 , mStrokeStyle( strokeStyle )
60 , mStrokeWidth( strokeWidth )
61 , mPenJoinStyle( penJoinStyle )
105void QgsSimpleFillSymbolLayer::applyDataDefinedSymbology(
QgsSymbolRenderContext &context, QBrush &brush, QPen &pen, QPen &selPen )
130 penColor.setAlphaF( context.
opacity() * penColor.alphaF() );
131 pen.setColor( penColor );
139 double width = exprVal.toDouble( &ok );
143 pen.setWidthF( width );
144 selPen.setWidthF( width );
181 if ( props.contains( QStringLiteral(
"color" ) ) )
183 if ( props.contains( QStringLiteral(
"style" ) ) )
185 if ( props.contains( QStringLiteral(
"color_border" ) ) )
190 else if ( props.contains( QStringLiteral(
"outline_color" ) ) )
194 else if ( props.contains( QStringLiteral(
"line_color" ) ) )
199 if ( props.contains( QStringLiteral(
"style_border" ) ) )
204 else if ( props.contains( QStringLiteral(
"outline_style" ) ) )
208 else if ( props.contains( QStringLiteral(
"line_style" ) ) )
212 if ( props.contains( QStringLiteral(
"width_border" ) ) )
215 strokeWidth = props[QStringLiteral(
"width_border" )].toDouble();
217 else if ( props.contains( QStringLiteral(
"outline_width" ) ) )
219 strokeWidth = props[QStringLiteral(
"outline_width" )].toDouble();
221 else if ( props.contains( QStringLiteral(
"line_width" ) ) )
223 strokeWidth = props[QStringLiteral(
"line_width" )].toDouble();
225 if ( props.contains( QStringLiteral(
"offset" ) ) )
227 if ( props.contains( QStringLiteral(
"joinstyle" ) ) )
232 if ( props.contains( QStringLiteral(
"border_width_unit" ) ) )
236 else if ( props.contains( QStringLiteral(
"outline_width_unit" ) ) )
240 else if ( props.contains( QStringLiteral(
"line_width_unit" ) ) )
244 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
247 if ( props.contains( QStringLiteral(
"border_width_map_unit_scale" ) ) )
249 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
252 sl->restoreOldDataDefinedProperties( props );
260 return QStringLiteral(
"SimpleFill" );
272 selColor.setAlphaF( context.
opacity() );
330 if (
mBrush.style() == Qt::SolidPattern ||
mBrush.style() == Qt::NoBrush || !
dynamic_cast<QPrinter *
>( p->device() ) )
344 p->setPen( Qt::NoPen );
348 p->setBrush( Qt::NoBrush );
366 map[QStringLiteral(
"outline_width" )] = QString::number(
mStrokeWidth );
394 QDomElement symbolizerElem = doc.createElement( QStringLiteral(
"se:PolygonSymbolizer" ) );
395 if ( !props.value( QStringLiteral(
"uom" ), QString() ).toString().isEmpty() )
396 symbolizerElem.setAttribute( QStringLiteral(
"uom" ), props.value( QStringLiteral(
"uom" ), QString() ).toString() );
397 element.appendChild( symbolizerElem );
405 QDomElement fillElem = doc.createElement( QStringLiteral(
"se:Fill" ) );
406 symbolizerElem.appendChild( fillElem );
412 const double alpha { props.value( QStringLiteral(
"alpha" ), QVariant() ).toDouble( &ok ) };
423 QDomElement strokeElem = doc.createElement( QStringLiteral(
"se:Stroke" ) );
424 symbolizerElem.appendChild( strokeElem );
428 const double alpha { props.value( QStringLiteral(
"alpha" ), QVariant() ).toDouble( &ok ) };
447 symbolStyle.append(
';' );
456 Qt::BrushStyle fillStyle;
460 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
463 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
469 double scaleFactor = 1.0;
470 const QString uom = element.attribute( QStringLiteral(
"uom" ) );
477 sl->setOutputUnit( sldUnitSize );
486 return penBleed + offsetBleed;
547 : mGradientColorType( colorType )
548 , mGradientType( gradientType )
549 , mCoordinateMode( coordinateMode )
550 , mGradientSpread( spread )
551 , mReferencePoint1( QPointF( 0.5, 0 ) )
552 , mReferencePoint2( QPointF( 0.5, 1 ) )
573 bool refPoint1IsCentroid =
false;
575 bool refPoint2IsCentroid =
false;
580 if ( props.contains( QStringLiteral(
"type" ) ) )
582 if ( props.contains( QStringLiteral(
"coordinate_mode" ) ) )
584 if ( props.contains( QStringLiteral(
"spread" ) ) )
586 if ( props.contains( QStringLiteral(
"color_type" ) ) )
588 if ( props.contains( QStringLiteral(
"gradient_color" ) ) )
593 else if ( props.contains( QStringLiteral(
"color" ) ) )
597 if ( props.contains( QStringLiteral(
"gradient_color2" ) ) )
602 if ( props.contains( QStringLiteral(
"reference_point1" ) ) )
604 if ( props.contains( QStringLiteral(
"reference_point1_iscentroid" ) ) )
605 refPoint1IsCentroid = props[QStringLiteral(
"reference_point1_iscentroid" )].toInt();
606 if ( props.contains( QStringLiteral(
"reference_point2" ) ) )
608 if ( props.contains( QStringLiteral(
"reference_point2_iscentroid" ) ) )
609 refPoint2IsCentroid = props[QStringLiteral(
"reference_point2_iscentroid" )].toInt();
610 if ( props.contains( QStringLiteral(
"angle" ) ) )
611 angle = props[QStringLiteral(
"angle" )].toDouble();
613 if ( props.contains( QStringLiteral(
"offset" ) ) )
630 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
632 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
635 sl->setReferencePoint1IsCentroid( refPoint1IsCentroid );
637 sl->setReferencePoint2IsCentroid( refPoint2IsCentroid );
638 sl->setAngle(
angle );
640 sl->setColorRamp( gradientRamp );
642 sl->restoreOldDataDefinedProperties( props );
655 return QStringLiteral(
"GradientFill" );
658void QgsGradientFillSymbolLayer::applyDataDefinedSymbology(
QgsSymbolRenderContext &context,
const QPolygonF &points )
703 if ( currentType == QObject::tr(
"linear" ) )
707 else if ( currentType == QObject::tr(
"radial" ) )
711 else if ( currentType == QObject::tr(
"conical" ) )
725 if ( currentCoordMode == QObject::tr(
"feature" ) )
729 else if ( currentCoordMode == QObject::tr(
"viewport" ) )
743 if ( currentSpread == QObject::tr(
"pad" ) )
747 else if ( currentSpread == QObject::tr(
"repeat" ) )
751 else if ( currentSpread == QObject::tr(
"reflect" ) )
798 if ( refPoint1IsCentroid || refPoint2IsCentroid )
803 QRectF bbox = points.boundingRect();
804 double centroidX = (
centroid.
x() - bbox.left() ) / bbox.width();
805 double centroidY = (
centroid.
y() - bbox.top() ) / bbox.height();
807 if ( refPoint1IsCentroid )
809 refPoint1X = centroidX;
810 refPoint1Y = centroidY;
812 if ( refPoint2IsCentroid )
814 refPoint2X = centroidX;
815 refPoint2Y = centroidY;
821 spread, QPointF( refPoint1X, refPoint1Y ), QPointF( refPoint2X, refPoint2Y ),
angle );
824QPointF QgsGradientFillSymbolLayer::rotateReferencePoint( QPointF refPoint,
double angle )
829 QLineF refLine = QLineF( QPointF( 0.5, 0.5 ), refPoint );
831 refLine.setAngle( refLine.angle() +
angle );
833 QPointF rotatedReferencePoint = refLine.p2();
835 if ( rotatedReferencePoint.x() > 1 )
836 rotatedReferencePoint.setX( 1 );
837 if ( rotatedReferencePoint.x() < 0 )
838 rotatedReferencePoint.setX( 0 );
839 if ( rotatedReferencePoint.y() > 1 )
840 rotatedReferencePoint.setY( 1 );
841 if ( rotatedReferencePoint.y() < 0 )
842 rotatedReferencePoint.setY( 0 );
844 return rotatedReferencePoint;
851 QPointF referencePoint1, QPointF referencePoint2,
const double angle )
856 QColor fillColor2 =
color2;
857 fillColor2.setAlphaF( context.
opacity() * fillColor2.alphaF() );
868 gradient = QLinearGradient( rotatedReferencePoint1, rotatedReferencePoint2 );
871 gradient = QRadialGradient( rotatedReferencePoint1, QLineF( rotatedReferencePoint1, rotatedReferencePoint2 ).length() );
874 gradient = QConicalGradient( rotatedReferencePoint1, QLineF( rotatedReferencePoint1, rotatedReferencePoint2 ).
angle() );
880 gradient.setCoordinateMode( QGradient::ObjectBoundingMode );
883 gradient.setCoordinateMode( QGradient::StretchToDeviceMode );
889 gradient.setSpread( QGradient::PadSpread );
892 gradient.setSpread( QGradient::ReflectSpread );
895 gradient.setSpread( QGradient::RepeatSpread );
911 gradient.setColorAt( 1.0, fillColor2 );
915 brush = QBrush( gradient );
922 selColor.setAlphaF( context.
opacity() );
939 applyDataDefinedSymbology( context, points );
942 p->setPen( Qt::NoPen );
975 map[QStringLiteral(
"color_type" )] = QString::number(
static_cast< int >(
mGradientColorType ) );
976 map[QStringLiteral(
"type" )] = QString::number(
static_cast<int>(
mGradientType ) );
977 map[QStringLiteral(
"coordinate_mode" )] = QString::number(
static_cast< int >(
mCoordinateMode ) );
978 map[QStringLiteral(
"spread" )] = QString::number(
static_cast< int >(
mGradientSpread ) );
983 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
989#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
1013 return sl.release();
1055 int blurRadius,
bool useWholeShape,
double maxDistance )
1056 : mBlurRadius( blurRadius )
1057 , mUseWholeShape( useWholeShape )
1058 , mMaxDistance( maxDistance )
1059 , mColorType( colorType )
1078 if ( props.contains( QStringLiteral(
"color_type" ) ) )
1082 if ( props.contains( QStringLiteral(
"shapeburst_color" ) ) )
1087 else if ( props.contains( QStringLiteral(
"color" ) ) )
1092 if ( props.contains( QStringLiteral(
"shapeburst_color2" ) ) )
1097 else if ( props.contains( QStringLiteral(
"gradient_color2" ) ) )
1101 if ( props.contains( QStringLiteral(
"blur_radius" ) ) )
1103 blurRadius = props[QStringLiteral(
"blur_radius" )].toInt();
1105 if ( props.contains( QStringLiteral(
"use_whole_shape" ) ) )
1107 useWholeShape = props[QStringLiteral(
"use_whole_shape" )].toInt();
1109 if ( props.contains( QStringLiteral(
"max_distance" ) ) )
1111 maxDistance = props[QStringLiteral(
"max_distance" )].toDouble();
1113 if ( props.contains( QStringLiteral(
"offset" ) ) )
1132 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
1136 if ( props.contains( QStringLiteral(
"distance_unit" ) ) )
1140 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
1144 if ( props.contains( QStringLiteral(
"distance_map_unit_scale" ) ) )
1148 if ( props.contains( QStringLiteral(
"ignore_rings" ) ) )
1150 sl->setIgnoreRings( props[QStringLiteral(
"ignore_rings" )].toInt() );
1154 sl->setColorRamp( gradientRamp );
1157 sl->restoreOldDataDefinedProperties( props );
1159 return sl.release();
1164 return QStringLiteral(
"ShapeburstFill" );
1169 if ( mGradientRamp.get() == ramp )
1172 mGradientRamp.reset( ramp );
1175void QgsShapeburstFillSymbolLayer::applyDataDefinedSymbology(
QgsSymbolRenderContext &context, QColor &color, QColor &color2,
int &blurRadius,
bool &useWholeShape,
1176 double &maxDistance,
bool &ignoreRings )
1233 selColor.setAlphaF( context.
opacity() );
1234 mSelBrush = QBrush( selColor );
1253 p->setBrush( mSelBrush );
1254 QPointF
offset = mOffset;
1289 int outputPixelMaxDist = 0;
1297 std::unique_ptr< QgsGradientColorRamp > twoColorGradientRamp;
1300 twoColorGradientRamp = std::make_unique< QgsGradientColorRamp >( color1,
color2 );
1304 p->setPen( QPen( Qt::NoPen ) );
1309 int pointsWidth =
static_cast< int >( std::round( points.boundingRect().width() ) );
1310 int pointsHeight =
static_cast< int >( std::round( points.boundingRect().height() ) );
1311 int imWidth = pointsWidth + ( sideBuffer * 2 );
1312 int imHeight = pointsHeight + ( sideBuffer * 2 );
1318 std::unique_ptr< QImage > fillImage = std::make_unique< QImage >( imWidth,
1319 imHeight, QImage::Format_ARGB32_Premultiplied );
1320 if ( fillImage->isNull() )
1330 std::unique_ptr< QImage > alphaImage = std::make_unique< QImage >( fillImage->width(), fillImage->height(), QImage::Format_ARGB32_Premultiplied );
1331 if ( alphaImage->isNull() )
1343 fillImage->fill( Qt::black );
1349 alphaImage->fill( Qt::transparent );
1355 QPainter imgPainter;
1356 imgPainter.begin( alphaImage.get() );
1357 imgPainter.setRenderHint( QPainter::Antialiasing,
true );
1358 imgPainter.setBrush( QBrush( Qt::white ) );
1359 imgPainter.setPen( QPen( Qt::black ) );
1360 imgPainter.translate( -points.boundingRect().left() + sideBuffer, - points.boundingRect().top() + sideBuffer );
1369 imgPainter.begin( fillImage.get() );
1372 imgPainter.drawImage( 0, 0, *alphaImage );
1379 imgPainter.setBrush( QBrush( Qt::white ) );
1380 imgPainter.setPen( QPen( Qt::black ) );
1381 imgPainter.translate( -points.boundingRect().left() + sideBuffer, - points.boundingRect().top() + sideBuffer );
1390 double *dtArray = distanceTransform( fillImage.get(), context.
renderContext() );
1410 imgPainter.begin( fillImage.get() );
1411 imgPainter.setCompositionMode( QPainter::CompositionMode_DestinationIn );
1412 imgPainter.drawImage( 0, 0, *alphaImage );
1420 QPointF
offset = mOffset;
1437 p->drawImage( points.boundingRect().left() - sideBuffer, points.boundingRect().top() - sideBuffer, *fillImage );
1448void QgsShapeburstFillSymbolLayer::distanceTransform1d(
double *f,
int n,
int *v,
double *z,
double *d )
1454 for (
int q = 1; q <= n - 1; q++ )
1456 double s = ( ( f[q] + q * q ) - ( f[v[k]] + ( v[k] * v[k] ) ) ) / ( 2 * q - 2 * v[k] );
1460 s = ( ( f[q] + q * q ) - ( f[v[k]] + ( v[k] * v[k] ) ) ) / ( 2 * q - 2 * v[k] );
1469 for (
int q = 0; q <= n - 1; q++ )
1471 while ( z[k + 1] < q )
1473 d[q] = ( q - v[k] ) * ( q - v[k] ) + f[v[k]];
1478void QgsShapeburstFillSymbolLayer::distanceTransform2d(
double *im,
int width,
int height,
QgsRenderContext &context )
1480 int maxDimension = std::max( width, height );
1481 double *f =
new double[ maxDimension ];
1482 int *v =
new int[ maxDimension ];
1483 double *z =
new double[ maxDimension + 1 ];
1484 double *d =
new double[ maxDimension ];
1487 for (
int x = 0; x < width; x++ )
1492 for (
int y = 0; y < height; y++ )
1494 f[y] = im[ x + y * width ];
1496 distanceTransform1d( f, height, v, z, d );
1497 for (
int y = 0; y < height; y++ )
1499 im[ x + y * width ] = d[y];
1504 for (
int y = 0; y < height; y++ )
1509 for (
int x = 0; x < width; x++ )
1511 f[x] = im[ x + y * width ];
1513 distanceTransform1d( f, width, v, z, d );
1514 for (
int x = 0; x < width; x++ )
1516 im[ x + y * width ] = d[x];
1527double *QgsShapeburstFillSymbolLayer::distanceTransform( QImage *im,
QgsRenderContext &context )
1529 int width = im->width();
1530 int height = im->height();
1532 double *dtArray =
new double[width * height];
1537 for (
int heightIndex = 0; heightIndex < height; ++heightIndex )
1542 const QRgb *scanLine =
reinterpret_cast< const QRgb *
>( im->constScanLine( heightIndex ) );
1543 for (
int widthIndex = 0; widthIndex < width; ++widthIndex )
1545 tmpRgb = scanLine[widthIndex];
1546 if ( qRed( tmpRgb ) == 0 )
1554 dtArray[ idx ] =
INF;
1561 distanceTransform2d( dtArray, width, height, context );
1566void QgsShapeburstFillSymbolLayer::dtArrayToQImage(
double *array, QImage *im,
QgsColorRamp *ramp,
QgsRenderContext &context,
bool useWholeShape,
int maxPixelDistance )
1568 int width = im->width();
1569 int height = im->height();
1572 double maxDistanceValue;
1577 double dtMaxValue = array[0];
1578 for (
int i = 1; i < ( width * height ); ++i )
1580 if ( array[i] > dtMaxValue )
1582 dtMaxValue = array[i];
1587 maxDistanceValue = std::sqrt( dtMaxValue );
1592 maxDistanceValue = maxPixelDistance;
1597 double squaredVal = 0;
1600 for (
int heightIndex = 0; heightIndex < height; ++heightIndex )
1605 QRgb *scanLine =
reinterpret_cast< QRgb *
>( im->scanLine( heightIndex ) );
1606 for (
int widthIndex = 0; widthIndex < width; ++widthIndex )
1609 squaredVal = array[idx];
1612 if ( maxDistanceValue > 0 )
1614 pixVal = squaredVal > 0 ? std::min( ( std::sqrt( squaredVal ) / maxDistanceValue ), 1.0 ) : 0;
1623 scanLine[widthIndex] = qPremultiply( ramp->
color( pixVal ).rgba() );
1634 map[QStringLiteral(
"color_type" )] = QString::number(
static_cast< int >( mColorType ) );
1635 map[QStringLiteral(
"blur_radius" )] = QString::number( mBlurRadius );
1636 map[QStringLiteral(
"use_whole_shape" )] = QString::number( mUseWholeShape );
1637 map[QStringLiteral(
"max_distance" )] = QString::number( mMaxDistance );
1640 map[QStringLiteral(
"ignore_rings" )] = QString::number( mIgnoreRings );
1644 if ( mGradientRamp )
1646#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
1647 map.unite( mGradientRamp->properties() );
1649 map.insert( mGradientRamp->properties() );
1658 std::unique_ptr< QgsShapeburstFillSymbolLayer > sl = std::make_unique< QgsShapeburstFillSymbolLayer >(
mColor, mColor2, mColorType, mBlurRadius, mUseWholeShape, mMaxDistance );
1659 if ( mGradientRamp )
1661 sl->setColorRamp( mGradientRamp->clone() );
1663 sl->setDistanceUnit( mDistanceUnit );
1664 sl->setDistanceMapUnitScale( mDistanceMapUnitScale );
1665 sl->setIgnoreRings( mIgnoreRings );
1666 sl->setOffset( mOffset );
1667 sl->setOffsetUnit( mOffsetUnit );
1668 sl->setOffsetMapUnitScale( mOffsetMapUnitScale );
1671 return sl.release();
1676 double offsetBleed = context.
convertToPainterUnits( std::max( std::fabs( mOffset.x() ), std::fabs( mOffset.y() ) ), mOffsetUnit, mOffsetMapUnitScale );
1687 mDistanceUnit = unit;
1693 if ( mDistanceUnit == mOffsetUnit )
1695 return mDistanceUnit;
1708 mDistanceMapUnitScale = scale;
1709 mOffsetMapUnitScale = scale;
1714 if ( mDistanceMapUnitScale == mOffsetMapUnitScale )
1716 return mDistanceMapUnitScale;
1741 p->setPen( QPen( Qt::NoPen ) );
1743 QTransform bkTransform =
mBrush.transform();
1747 QTransform t =
mBrush.transform();
1748 t.translate( leftCorner.x(), leftCorner.y() );
1749 mBrush.setTransform( t );
1753 QTransform t =
mBrush.transform();
1754 t.translate( 0, 0 );
1755 mBrush.setTransform( t );
1761 p->setBrush( QBrush( selColor ) );
1767 QTransform t =
mBrush.transform();
1769 mBrush.setTransform( t );
1774 mBrush.setTransform( bkTransform );
1810 return Qt::SolidLine;
1814 return Qt::SolidLine;
1818 return mStroke->dxfPenStyle();
1854 , mPatternWidth( width )
1858 mColor = QColor( 255, 255, 255 );
1864 , mPatternWidth( width )
1865 , mSvgData( svgData )
1870 mColor = QColor( 255, 255, 255 );
1871 setDefaultSvgParams();
1879 mPatternWidthUnit = unit;
1880 mSvgStrokeWidthUnit = unit;
1883 mStroke->setOutputUnit( unit );
1889 if ( mPatternWidthUnit != unit || mSvgStrokeWidthUnit != unit ||
mStrokeWidthUnit != unit )
1899 mPatternWidthMapUnitScale = scale;
1900 mSvgStrokeWidthMapUnitScale = scale;
1906 mPatternWidthMapUnitScale == mSvgStrokeWidthMapUnitScale &&
1909 return mPatternWidthMapUnitScale;
1919 mSvgFilePath = svgPath;
1920 setDefaultSvgParams();
1930 if (
properties.contains( QStringLiteral(
"width" ) ) )
1932 width =
properties[QStringLiteral(
"width" )].toDouble();
1934 if (
properties.contains( QStringLiteral(
"svgFile" ) ) )
1938 if (
properties.contains( QStringLiteral(
"angle" ) ) )
1943 std::unique_ptr< QgsSVGFillSymbolLayer > symbolLayer;
1946 symbolLayer = std::make_unique< QgsSVGFillSymbolLayer >(
svgFilePath, width,
angle );
1950 if (
properties.contains( QStringLiteral(
"data" ) ) )
1952 data = QByteArray::fromHex(
properties[QStringLiteral(
"data" )].toString().toLocal8Bit() );
1954 symbolLayer = std::make_unique< QgsSVGFillSymbolLayer >( data, width,
angle );
1958 if (
properties.contains( QStringLiteral(
"svgFillColor" ) ) )
1963 else if (
properties.contains( QStringLiteral(
"color" ) ) )
1967 if (
properties.contains( QStringLiteral(
"svgOutlineColor" ) ) )
1972 else if (
properties.contains( QStringLiteral(
"outline_color" ) ) )
1976 else if (
properties.contains( QStringLiteral(
"line_color" ) ) )
1980 if (
properties.contains( QStringLiteral(
"svgOutlineWidth" ) ) )
1983 symbolLayer->setSvgStrokeWidth(
properties[QStringLiteral(
"svgOutlineWidth" )].toDouble() );
1985 else if (
properties.contains( QStringLiteral(
"outline_width" ) ) )
1987 symbolLayer->setSvgStrokeWidth(
properties[QStringLiteral(
"outline_width" )].toDouble() );
1989 else if (
properties.contains( QStringLiteral(
"line_width" ) ) )
1991 symbolLayer->setSvgStrokeWidth(
properties[QStringLiteral(
"line_width" )].toDouble() );
1995 if (
properties.contains( QStringLiteral(
"pattern_width_unit" ) ) )
1999 if (
properties.contains( QStringLiteral(
"pattern_width_map_unit_scale" ) ) )
2003 if (
properties.contains( QStringLiteral(
"svg_outline_width_unit" ) ) )
2007 if (
properties.contains( QStringLiteral(
"svg_outline_width_map_unit_scale" ) ) )
2011 if (
properties.contains( QStringLiteral(
"outline_width_unit" ) ) )
2015 if (
properties.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
2020 if (
properties.contains( QStringLiteral(
"parameters" ) ) )
2026 symbolLayer->restoreOldDataDefinedProperties(
properties );
2028 return symbolLayer.release();
2033 QVariantMap::iterator it =
properties.find( QStringLiteral(
"svgFile" ) );
2045 return QStringLiteral(
"SVGFill" );
2048void QgsSVGFillSymbolLayer::applyPattern( QBrush &brush,
const QString &svgFilePath,
double patternWidth,
QgsUnitTypes::RenderUnit patternWidthUnit,
2049 const QColor &svgFillColor,
const QColor &svgStrokeColor,
double svgStrokeWidth,
2053 if ( mSvgViewBox.isNull() )
2060 if (
static_cast< int >( size ) < 1.0 || 10000.0 < size )
2062 brush.setTextureImage( QImage() );
2066 bool fitsInCache =
true;
2074 double hwRatio = 1.0;
2075 if ( patternPict.width() > 0 )
2077 hwRatio =
static_cast< double >( patternPict.height() ) /
static_cast< double >( patternPict.width() );
2079 patternImage = QImage(
static_cast< int >( size ),
static_cast< int >( size * hwRatio ), QImage::Format_ARGB32_Premultiplied );
2080 patternImage.fill( 0 );
2082 QPainter p( &patternImage );
2083 p.drawPicture( QPointF( size / 2, size * hwRatio / 2 ), patternPict );
2086 QTransform brushTransform;
2089 QImage transparentImage = patternImage.copy();
2091 brush.setTextureImage( transparentImage );
2095 brush.setTextureImage( patternImage );
2097 brush.setTransform( brushTransform );
2105 applyPattern(
mBrush, mSvgFilePath, mPatternWidth, mPatternWidthUnit,
mColor, mSvgStrokeColor, mSvgStrokeWidth, mSvgStrokeWidthUnit, context, mPatternWidthMapUnitScale, mSvgStrokeWidthMapUnitScale, evaluatedParameters );
2130 for (
auto ringIt = rings->constBegin(); ringIt != rings->constEnd(); ++ringIt )
2141 if ( !mSvgFilePath.isEmpty() )
2143 map.insert( QStringLiteral(
"svgFile" ), mSvgFilePath );
2147 map.insert( QStringLiteral(
"data" ), QString( mSvgData.toHex() ) );
2150 map.insert( QStringLiteral(
"width" ), QString::number( mPatternWidth ) );
2151 map.insert( QStringLiteral(
"angle" ), QString::number(
mAngle ) );
2156 map.insert( QStringLiteral(
"outline_width" ), QString::number( mSvgStrokeWidth ) );
2173 std::unique_ptr< QgsSVGFillSymbolLayer > clonedLayer;
2174 if ( !mSvgFilePath.isEmpty() )
2176 clonedLayer = std::make_unique< QgsSVGFillSymbolLayer >( mSvgFilePath, mPatternWidth,
mAngle );
2177 clonedLayer->setSvgFillColor(
mColor );
2178 clonedLayer->setSvgStrokeColor( mSvgStrokeColor );
2179 clonedLayer->setSvgStrokeWidth( mSvgStrokeWidth );
2183 clonedLayer = std::make_unique< QgsSVGFillSymbolLayer >( mSvgData, mPatternWidth,
mAngle );
2186 clonedLayer->setPatternWidthUnit( mPatternWidthUnit );
2187 clonedLayer->setPatternWidthMapUnitScale( mPatternWidthMapUnitScale );
2188 clonedLayer->setSvgStrokeWidthUnit( mSvgStrokeWidthUnit );
2189 clonedLayer->setSvgStrokeWidthMapUnitScale( mSvgStrokeWidthMapUnitScale );
2193 clonedLayer->setParameters( mParameters );
2197 clonedLayer->setSubSymbol( mStroke->clone() );
2201 return clonedLayer.release();
2206 QDomElement symbolizerElem = doc.createElement( QStringLiteral(
"se:PolygonSymbolizer" ) );
2207 if ( !props.value( QStringLiteral(
"uom" ), QString() ).toString().isEmpty() )
2208 symbolizerElem.setAttribute( QStringLiteral(
"uom" ), props.value( QStringLiteral(
"uom" ), QString() ).toString() );
2209 element.appendChild( symbolizerElem );
2213 QDomElement fillElem = doc.createElement( QStringLiteral(
"se:Fill" ) );
2214 symbolizerElem.appendChild( fillElem );
2216 QDomElement graphicFillElem = doc.createElement( QStringLiteral(
"se:GraphicFill" ) );
2217 fillElem.appendChild( graphicFillElem );
2219 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
2220 graphicFillElem.appendChild( graphicElem );
2222 if ( !mSvgFilePath.isEmpty() )
2233 symbolizerElem.appendChild( doc.createComment( QStringLiteral(
"SVG from data not implemented yet" ) ) );
2239 double angle = props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toDouble( &ok );
2242 angleFunc = QStringLiteral(
"%1 + %2" ).arg( props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toString() ).arg(
mAngle );
2255 mStroke->toSld( doc, element, props );
2267 return mStroke.get();
2274 mStroke.reset(
nullptr );
2287 mStroke.reset( lineSymbol );
2297 if ( mStroke && mStroke->symbolLayer( 0 ) )
2299 double subLayerBleed = mStroke->symbolLayer( 0 )->estimateMaxBleed( context );
2300 return subLayerBleed;
2310 return QColor( Qt::black );
2312 return mStroke->color();
2319 attr.unite( mStroke->usedAttributes( context ) );
2327 if ( mStroke && mStroke->hasDataDefinedProperties() )
2334 QString path, mimeType;
2336 Qt::PenStyle penStyle;
2337 double size, strokeWidth;
2339 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
2340 if ( fillElem.isNull() )
2343 QDomElement graphicFillElem = fillElem.firstChildElement( QStringLiteral(
"GraphicFill" ) );
2344 if ( graphicFillElem.isNull() )
2347 QDomElement graphicElem = graphicFillElem.firstChildElement( QStringLiteral(
"Graphic" ) );
2348 if ( graphicElem.isNull() )
2354 if ( mimeType != QLatin1String(
"image/svg+xml" ) )
2359 double scaleFactor = 1.0;
2360 const QString uom = element.attribute( QStringLiteral(
"uom" ) );
2362 size = size * scaleFactor;
2363 strokeWidth = strokeWidth * scaleFactor;
2370 double d = angleFunc.toDouble( &ok );
2375 std::unique_ptr< QgsSVGFillSymbolLayer > sl = std::make_unique< QgsSVGFillSymbolLayer >( path, size,
angle );
2376 sl->setOutputUnit( sldUnitSize );
2379 sl->setSvgStrokeWidth( strokeWidth );
2382 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
2383 if ( !strokeElem.isNull() )
2394 return sl.release();
2412 double width = mPatternWidth;
2418 QString svgFile = mSvgFilePath;
2437 double strokeWidth = mSvgStrokeWidth;
2446 mSvgStrokeWidthUnit, context, mPatternWidthMapUnitScale, mSvgStrokeWidthMapUnitScale, evaluatedParameters );
2450void QgsSVGFillSymbolLayer::storeViewBox()
2452 if ( !mSvgData.isEmpty() )
2454 QSvgRenderer r( mSvgData );
2457 mSvgViewBox = r.viewBoxF();
2462 mSvgViewBox = QRectF();
2465void QgsSVGFillSymbolLayer::setDefaultSvgParams()
2467 if ( mSvgFilePath.isEmpty() )
2472 bool hasFillParam, hasFillOpacityParam, hasStrokeParam, hasStrokeWidthParam, hasStrokeOpacityParam;
2473 bool hasDefaultFillColor, hasDefaultFillOpacity, hasDefaultStrokeColor, hasDefaultStrokeWidth, hasDefaultStrokeOpacity;
2474 QColor defaultFillColor, defaultStrokeColor;
2475 double defaultStrokeWidth, defaultFillOpacity, defaultStrokeOpacity;
2477 hasFillOpacityParam, hasDefaultFillOpacity, defaultFillOpacity,
2478 hasStrokeParam, hasDefaultStrokeColor, defaultStrokeColor,
2479 hasStrokeWidthParam, hasDefaultStrokeWidth, defaultStrokeWidth,
2480 hasStrokeOpacityParam, hasDefaultStrokeOpacity, defaultStrokeOpacity );
2482 double newFillOpacity = hasFillOpacityParam ?
mColor.alphaF() : 1.0;
2483 double newStrokeOpacity = hasStrokeOpacityParam ? mSvgStrokeColor.alphaF() : 1.0;
2485 if ( hasDefaultFillColor )
2487 mColor = defaultFillColor;
2488 mColor.setAlphaF( newFillOpacity );
2490 if ( hasDefaultFillOpacity )
2492 mColor.setAlphaF( defaultFillOpacity );
2494 if ( hasDefaultStrokeColor )
2496 mSvgStrokeColor = defaultStrokeColor;
2497 mSvgStrokeColor.setAlphaF( newStrokeOpacity );
2499 if ( hasDefaultStrokeOpacity )
2501 mSvgStrokeColor.setAlphaF( defaultStrokeOpacity );
2503 if ( hasDefaultStrokeWidth )
2505 mSvgStrokeWidth = defaultStrokeWidth;
2526 mFillLineSymbol->setWidth( w );
2532 mFillLineSymbol->setColor(
c );
2538 return mFillLineSymbol ? mFillLineSymbol->color() :
mColor;
2550 mFillLineSymbol.reset( qgis::down_cast<QgsLineSymbol *>( symbol ) );
2559 return mFillLineSymbol.get();
2565 if ( mFillLineSymbol )
2566 attr.unite( mFillLineSymbol->usedAttributes( context ) );
2574 if ( mFillLineSymbol && mFillLineSymbol->hasDataDefinedProperties() )
2597 mDistanceUnit = unit;
2598 mLineWidthUnit = unit;
2601 if ( mFillLineSymbol )
2602 mFillLineSymbol->setOutputUnit( unit );
2625 mDistanceMapUnitScale = scale;
2626 mLineWidthMapUnitScale = scale;
2627 mOffsetMapUnitScale = scale;
2633 mDistanceMapUnitScale == mLineWidthMapUnitScale &&
2634 mLineWidthMapUnitScale == mOffsetMapUnitScale )
2636 return mDistanceMapUnitScale;
2643 std::unique_ptr< QgsLinePatternFillSymbolLayer > patternLayer = std::make_unique< QgsLinePatternFillSymbolLayer >();
2649 QColor
color( Qt::black );
2652 if (
properties.contains( QStringLiteral(
"lineangle" ) ) )
2657 else if (
properties.contains( QStringLiteral(
"angle" ) ) )
2661 patternLayer->setLineAngle(
lineAngle );
2663 if (
properties.contains( QStringLiteral(
"distance" ) ) )
2667 patternLayer->setDistance(
distance );
2669 if (
properties.contains( QStringLiteral(
"linewidth" ) ) )
2674 else if (
properties.contains( QStringLiteral(
"outline_width" ) ) )
2678 else if (
properties.contains( QStringLiteral(
"line_width" ) ) )
2682 patternLayer->setLineWidth(
lineWidth );
2684 if (
properties.contains( QStringLiteral(
"color" ) ) )
2688 else if (
properties.contains( QStringLiteral(
"outline_color" ) ) )
2692 else if (
properties.contains( QStringLiteral(
"line_color" ) ) )
2696 patternLayer->setColor(
color );
2698 if (
properties.contains( QStringLiteral(
"offset" ) ) )
2702 patternLayer->setOffset(
offset );
2705 if (
properties.contains( QStringLiteral(
"distance_unit" ) ) )
2709 if (
properties.contains( QStringLiteral(
"distance_map_unit_scale" ) ) )
2713 if (
properties.contains( QStringLiteral(
"line_width_unit" ) ) )
2717 else if (
properties.contains( QStringLiteral(
"outline_width_unit" ) ) )
2721 if (
properties.contains( QStringLiteral(
"line_width_map_unit_scale" ) ) )
2725 if (
properties.contains( QStringLiteral(
"offset_unit" ) ) )
2729 if (
properties.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
2733 if (
properties.contains( QStringLiteral(
"outline_width_unit" ) ) )
2737 if (
properties.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
2741 if (
properties.contains( QStringLiteral(
"coordinate_reference" ) ) )
2745 if (
properties.contains( QStringLiteral(
"clip_mode" ) ) )
2750 patternLayer->restoreOldDataDefinedProperties(
properties );
2752 return patternLayer.release();
2757 return QStringLiteral(
"LinePatternFill" );
2760void QgsLinePatternFillSymbolLayer::applyPattern(
const QgsSymbolRenderContext &context, QBrush &brush,
double lineAngle,
double distance )
2762 mBrush.setTextureImage( QImage() );
2764 if ( !mFillLineSymbol )
2769 std::unique_ptr< QgsLineSymbol > fillLineSymbol( mFillLineSymbol->clone() );
2770 if ( !fillLineSymbol )
2786 outputPixelOffset = std::fmod( outputPixelOffset, outputPixelDist );
2787 if ( outputPixelOffset > outputPixelDist / 2.0 )
2788 outputPixelOffset -= outputPixelDist;
2792 double outputPixelBleed = 0;
2793 double outputPixelInterval = 0;
2794 for (
int i = 0; i < fillLineSymbol->symbolLayerCount(); i++ )
2798 outputPixelBleed = std::max( outputPixelBleed, outputPixelLayerBleed );
2801 if ( markerLineLayer )
2810 outputPixelInterval = std::max( outputPixelInterval, outputPixelLayerInterval );
2814 if ( outputPixelInterval > 0 )
2818 double intervalScale = std::round( outputPixelInterval ) / outputPixelInterval;
2819 outputPixelInterval = std::round( outputPixelInterval );
2821 for (
int i = 0; i < fillLineSymbol->symbolLayerCount(); i++ )
2826 if ( markerLineLayer )
2840 height = outputPixelDist;
2841 width = outputPixelInterval > 0 ? outputPixelInterval : height;
2845 width = outputPixelDist;
2846 height = outputPixelInterval > 0 ? outputPixelInterval : width;
2850 height = outputPixelDist / std::cos(
lineAngle * M_PI / 180 );
2851 width = outputPixelDist / std::sin(
lineAngle * M_PI / 180 );
2854 lineAngle = 180 * std::atan2(
static_cast< double >( height ),
static_cast< double >( width ) ) / M_PI;
2860 height = std::abs( height );
2861 width = std::abs( width );
2863 outputPixelDist = std::abs( height * std::cos(
lineAngle * M_PI / 180 ) );
2867 int offsetHeight =
static_cast< int >( std::round( outputPixelOffset / std::cos(
lineAngle * M_PI / 180 ) ) );
2868 outputPixelOffset = offsetHeight * std::cos(
lineAngle * M_PI / 180 );
2877 int bufferMulti =
static_cast< int >( std::max( std::ceil( outputPixelBleed / width ), std::ceil( outputPixelBleed / width ) ) );
2881 bufferMulti = std::max( bufferMulti, 1 );
2883 int xBuffer = width * bufferMulti;
2884 int yBuffer = height * bufferMulti;
2885 int innerWidth = width;
2886 int innerHeight = height;
2887 width += 2 * xBuffer;
2888 height += 2 * yBuffer;
2891 if ( width > 10000 || height > 10000 || width == 0 || height == 0 )
2896 QImage patternImage( width, height, QImage::Format_ARGB32 );
2897 patternImage.fill( 0 );
2899 QPointF p1, p2, p3, p4, p5, p6;
2902 p1 = QPointF( 0, yBuffer );
2903 p2 = QPointF( width, yBuffer );
2904 p3 = QPointF( 0, yBuffer + innerHeight );
2905 p4 = QPointF( width, yBuffer + innerHeight );
2909 p1 = QPointF( xBuffer, height );
2910 p2 = QPointF( xBuffer, 0 );
2911 p3 = QPointF( xBuffer + innerWidth, height );
2912 p4 = QPointF( xBuffer + innerWidth, 0 );
2916 dx = outputPixelDist * std::cos( ( 90 -
lineAngle ) * M_PI / 180.0 );
2917 dy = outputPixelDist * std::sin( ( 90 -
lineAngle ) * M_PI / 180.0 );
2918 p1 = QPointF( 0, height );
2919 p2 = QPointF( width, 0 );
2920 p3 = QPointF( -dx, height - dy );
2921 p4 = QPointF( width - dx, -dy );
2922 p5 = QPointF( dx, height + dy );
2923 p6 = QPointF( width + dx, dy );
2927 dx = outputPixelDist * std::cos( ( 90 -
lineAngle ) * M_PI / 180.0 );
2928 dy = outputPixelDist * std::sin( ( 90 -
lineAngle ) * M_PI / 180.0 );
2929 p1 = QPointF( width, 0 );
2930 p2 = QPointF( 0, height );
2931 p3 = QPointF( width - dx, -dy );
2932 p4 = QPointF( -dx, height - dy );
2933 p5 = QPointF( width + dx, dy );
2934 p6 = QPointF( dx, height + dy );
2938 dy = outputPixelDist * std::cos( ( 180 -
lineAngle ) * M_PI / 180 );
2939 dx = outputPixelDist * std::sin( ( 180 -
lineAngle ) * M_PI / 180 );
2940 p1 = QPointF( 0, 0 );
2941 p2 = QPointF( width, height );
2942 p5 = QPointF( dx, -dy );
2943 p6 = QPointF( width + dx, height - dy );
2944 p3 = QPointF( -dx, dy );
2945 p4 = QPointF( width - dx, height + dy );
2949 dy = outputPixelDist * std::cos( ( 180 -
lineAngle ) * M_PI / 180 );
2950 dx = outputPixelDist * std::sin( ( 180 -
lineAngle ) * M_PI / 180 );
2951 p1 = QPointF( width, height );
2952 p2 = QPointF( 0, 0 );
2953 p5 = QPointF( width + dx, height - dy );
2954 p6 = QPointF( dx, -dy );
2955 p3 = QPointF( width - dx, height + dy );
2956 p4 = QPointF( -dx, dy );
2963 p3 = QPointF( tempPt.x(), tempPt.y() );
2965 p4 = QPointF( tempPt.x(), tempPt.y() );
2967 p5 = QPointF( tempPt.x(), tempPt.y() );
2969 p6 = QPointF( tempPt.x(), tempPt.y() );
2973 p1 = QPointF( tempPt.x(), tempPt.y() );
2975 p2 = QPointF( tempPt.x(), tempPt.y() );
2978 QPainter p( &patternImage );
2982 p.setRenderHint( QPainter::Antialiasing,
false );
2983 QPen pen( QColor( Qt::black ) );
2984 pen.setWidthF( 0.1 );
2985 pen.setCapStyle( Qt::FlatCap );
2990 QPolygon polygon = QPolygon() << QPoint( 0, 0 ) << QPoint( width - 1, 0 ) << QPoint( width - 1, height - 1 ) << QPoint( 0, height - 1 ) << QPoint( 0, 0 );
2991 p.drawPolygon( polygon );
2993 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 );
2994 p.drawPolygon( polygon );
3000 p.setRenderHint( QPainter::Antialiasing,
true );
3012 fillLineSymbol->startRender( lineRenderContext, context.
fields() );
3014 QVector<QPolygonF> polygons;
3015 polygons.append( QPolygonF() << p1 << p2 );
3016 polygons.append( QPolygonF() << p3 << p4 );
3019 polygons.append( QPolygonF() << p5 << p6 );
3022 for (
const QPolygonF &polygon : std::as_const( polygons ) )
3024 fillLineSymbol->renderPolyline( polygon, context.
feature(), lineRenderContext, -1, context.
selected() );
3027 fillLineSymbol->stopRender( lineRenderContext );
3031 patternImage = patternImage.copy( xBuffer, yBuffer, patternImage.width() - 2 * xBuffer, patternImage.height() - 2 * yBuffer );
3036 QImage transparentImage = patternImage.copy();
3038 brush.setTextureImage( transparentImage );
3042 brush.setTextureImage( patternImage );
3045 QTransform brushTransform;
3046 brush.setTransform( brushTransform );
3054 || mFillLineSymbol->hasDataDefinedProperties()
3058 if ( mRenderUsingLines )
3060 if ( mFillLineSymbol )
3066 applyPattern( context,
mBrush, mLineAngle, mDistance );
3072 if ( mRenderUsingLines && mFillLineSymbol )
3080 if ( !mRenderUsingLines )
3114 outputPixelOffset = std::fmod( outputPixelOffset, outputPixelDistance );
3115 if ( outputPixelOffset > outputPixelDistance / 2.0 )
3116 outputPixelOffset -= outputPixelDistance;
3118 p->setPen( QPen( Qt::NoPen ) );
3123 p->setBrush( QBrush( selColor ) );
3147 std::unique_ptr< QgsPolygon > shapePolygon;
3148 std::unique_ptr< QgsGeometryEngine > shapeEngine;
3156 shapePolygon = std::make_unique< QgsPolygon >();
3160 for (
const QPolygonF &ring : *rings )
3166 shapeEngine->prepareGeometry();
3173 path.addPolygon( points );
3176 for (
const QPolygonF &ring : *rings )
3178 path.addPolygon( ring );
3181 p->setClipPath( path, Qt::IntersectClip );
3187 const QRectF boundingRect = points.boundingRect();
3189 QTransform invertedRotateTransform;
3195 QTransform transform;
3196 if ( applyBrushTransform )
3199 transform.translate( -boundingRect.center().x(),
3200 -boundingRect.center().y() );
3202 transform.translate( boundingRect.center().x(),
3203 boundingRect.center().y() );
3211 const QRectF transformedBounds = transform.map( points ).boundingRect();
3215 left = transformedBounds.left() - buffer * 2;
3216 top = transformedBounds.top() - buffer * 2;
3217 right = transformedBounds.right() + buffer * 2;
3218 bottom = transformedBounds.bottom() + buffer * 2;
3219 invertedRotateTransform = transform.inverted();
3221 if ( !applyBrushTransform )
3223 top -= transformedBounds.top() - ( outputPixelDistance * std::floor( transformedBounds.top() / outputPixelDistance ) );
3228 const bool needsExpressionContext = mFillLineSymbol->hasDataDefinedProperties();
3233 int currentLine = 0;
3234 for (
double currentY = top; currentY <= bottom; currentY += outputPixelDistance )
3239 if ( needsExpressionContext )
3243 double y1 = currentY;
3245 double y2 = currentY;
3246 invertedRotateTransform.map( left, currentY - outputPixelOffset, &x1, &y1 );
3247 invertedRotateTransform.map( right, currentY - outputPixelOffset, &x2, &y2 );
3252 std::unique_ptr< QgsAbstractGeometry > intersection( shapeEngine->intersection( &ls ) );
3253 for (
auto it = intersection->const_parts_begin(); it != intersection->const_parts_end(); ++it )
3255 if (
const QgsLineString *ls = qgsgeometry_cast< const QgsLineString * >( *it ) )
3263 mFillLineSymbol->renderPolyline( QPolygonF() << QPointF( x1, y1 ) << QPointF( x2, y2 ), context.
feature(), context.
renderContext() );
3275 map.insert( QStringLiteral(
"angle" ), QString::number( mLineAngle ) );
3276 map.insert( QStringLiteral(
"distance" ), QString::number( mDistance ) );
3277 map.insert( QStringLiteral(
"line_width" ), QString::number( mLineWidth ) );
3279 map.insert( QStringLiteral(
"offset" ), QString::number( mOffset ) );
3295 if ( mFillLineSymbol )
3306 QDomElement symbolizerElem = doc.createElement( QStringLiteral(
"se:PolygonSymbolizer" ) );
3307 if ( !props.value( QStringLiteral(
"uom" ), QString() ).toString().isEmpty() )
3308 symbolizerElem.setAttribute( QStringLiteral(
"uom" ), props.value( QStringLiteral(
"uom" ), QString() ).toString() );
3309 element.appendChild( symbolizerElem );
3314 QDomElement fillElem = doc.createElement( QStringLiteral(
"se:Fill" ) );
3315 symbolizerElem.appendChild( fillElem );
3317 QDomElement graphicFillElem = doc.createElement( QStringLiteral(
"se:GraphicFill" ) );
3318 fillElem.appendChild( graphicFillElem );
3320 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
3321 graphicFillElem.appendChild( graphicElem );
3324 QColor lineColor = mFillLineSymbol ? mFillLineSymbol->color() : QColor();
3325 double lineWidth = mFillLineSymbol ? mFillLineSymbol->width() : 0.0;
3333 double angle = props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toDouble( &ok );
3336 angleFunc = QStringLiteral(
"%1 + %2" ).arg( props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toString() ).arg( mLineAngle );
3340 angleFunc = QString::number(
angle + mLineAngle );
3345 QPointF lineOffset( std::sin( mLineAngle ) * mOffset, std::cos( mLineAngle ) * mOffset );
3352 QString featureStyle;
3353 featureStyle.append(
"Brush(" );
3354 featureStyle.append( QStringLiteral(
"fc:%1" ).arg(
mColor.name() ) );
3355 featureStyle.append( QStringLiteral(
",bc:%1" ).arg( QLatin1String(
"#00000000" ) ) );
3356 featureStyle.append(
",id:\"ogr-brush-2\"" );
3357 featureStyle.append( QStringLiteral(
",a:%1" ).arg( mLineAngle ) );
3358 featureStyle.append( QStringLiteral(
",s:%1" ).arg( mLineWidth * widthScaleFactor ) );
3359 featureStyle.append(
",dx:0mm" );
3360 featureStyle.append( QStringLiteral(
",dy:%1mm" ).arg( mDistance * widthScaleFactor ) );
3361 featureStyle.append(
')' );
3362 return featureStyle;
3368 && ( !mFillLineSymbol || !mFillLineSymbol->hasDataDefinedProperties() ) )
3393 Qt::PenStyle lineStyle;
3395 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
3396 if ( fillElem.isNull() )
3399 QDomElement graphicFillElem = fillElem.firstChildElement( QStringLiteral(
"GraphicFill" ) );
3400 if ( graphicFillElem.isNull() )
3403 QDomElement graphicElem = graphicFillElem.firstChildElement( QStringLiteral(
"Graphic" ) );
3404 if ( graphicElem.isNull() )
3410 if ( name != QLatin1String(
"horline" ) )
3418 double d = angleFunc.toDouble( &ok );
3427 offset = std::sqrt( std::pow( vectOffset.x(), 2 ) + std::pow( vectOffset.y(), 2 ) );
3430 double scaleFactor = 1.0;
3431 const QString uom = element.attribute( QStringLiteral(
"uom" ) );
3433 size = size * scaleFactor;
3436 std::unique_ptr< QgsLinePatternFillSymbolLayer > sl = std::make_unique< QgsLinePatternFillSymbolLayer >();
3437 sl->setOutputUnit( sldUnitSize );
3438 sl->setColor( lineColor );
3440 sl->setLineAngle(
angle );
3442 sl->setDistance( size );
3445 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
3446 if ( !strokeElem.isNull() )
3457 return sl.release();
3557 std::unique_ptr< QgsPointPatternFillSymbolLayer > layer = std::make_unique< QgsPointPatternFillSymbolLayer >();
3558 if (
properties.contains( QStringLiteral(
"distance_x" ) ) )
3560 layer->setDistanceX(
properties[QStringLiteral(
"distance_x" )].toDouble() );
3562 if (
properties.contains( QStringLiteral(
"distance_y" ) ) )
3564 layer->setDistanceY(
properties[QStringLiteral(
"distance_y" )].toDouble() );
3566 if (
properties.contains( QStringLiteral(
"displacement_x" ) ) )
3568 layer->setDisplacementX(
properties[QStringLiteral(
"displacement_x" )].toDouble() );
3570 if (
properties.contains( QStringLiteral(
"displacement_y" ) ) )
3572 layer->setDisplacementY(
properties[QStringLiteral(
"displacement_y" )].toDouble() );
3574 if (
properties.contains( QStringLiteral(
"offset_x" ) ) )
3576 layer->setOffsetX(
properties[QStringLiteral(
"offset_x" )].toDouble() );
3578 if (
properties.contains( QStringLiteral(
"offset_y" ) ) )
3580 layer->setOffsetY(
properties[QStringLiteral(
"offset_y" )].toDouble() );
3583 if (
properties.contains( QStringLiteral(
"distance_x_unit" ) ) )
3587 if (
properties.contains( QStringLiteral(
"distance_x_map_unit_scale" ) ) )
3591 if (
properties.contains( QStringLiteral(
"distance_y_unit" ) ) )
3595 if (
properties.contains( QStringLiteral(
"distance_y_map_unit_scale" ) ) )
3599 if (
properties.contains( QStringLiteral(
"displacement_x_unit" ) ) )
3603 if (
properties.contains( QStringLiteral(
"displacement_x_map_unit_scale" ) ) )
3607 if (
properties.contains( QStringLiteral(
"displacement_y_unit" ) ) )
3611 if (
properties.contains( QStringLiteral(
"displacement_y_map_unit_scale" ) ) )
3615 if (
properties.contains( QStringLiteral(
"offset_x_unit" ) ) )
3619 if (
properties.contains( QStringLiteral(
"offset_x_map_unit_scale" ) ) )
3623 if (
properties.contains( QStringLiteral(
"offset_y_unit" ) ) )
3627 if (
properties.contains( QStringLiteral(
"offset_y_map_unit_scale" ) ) )
3632 if (
properties.contains( QStringLiteral(
"random_deviation_x" ) ) )
3634 layer->setMaximumRandomDeviationX(
properties[QStringLiteral(
"random_deviation_x" )].toDouble() );
3636 if (
properties.contains( QStringLiteral(
"random_deviation_y" ) ) )
3638 layer->setMaximumRandomDeviationY(
properties[QStringLiteral(
"random_deviation_y" )].toDouble() );
3640 if (
properties.contains( QStringLiteral(
"random_deviation_x_unit" ) ) )
3644 if (
properties.contains( QStringLiteral(
"random_deviation_x_map_unit_scale" ) ) )
3648 if (
properties.contains( QStringLiteral(
"random_deviation_y_unit" ) ) )
3652 if (
properties.contains( QStringLiteral(
"random_deviation_y_map_unit_scale" ) ) )
3656 unsigned long seed = 0;
3657 if (
properties.contains( QStringLiteral(
"seed" ) ) )
3663 std::random_device rd;
3664 std::mt19937 mt(
seed == 0 ? rd() :
seed );
3665 std::uniform_int_distribution<> uniformDist( 1, 999999999 );
3666 seed = uniformDist( mt );
3668 layer->setSeed(
seed );
3670 if (
properties.contains( QStringLiteral(
"outline_width_unit" ) ) )
3674 if (
properties.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
3678 if (
properties.contains( QStringLiteral(
"clip_mode" ) ) )
3682 if (
properties.contains( QStringLiteral(
"coordinate_reference" ) ) )
3687 if (
properties.contains( QStringLiteral(
"angle" ) ) )
3689 layer->setAngle(
properties[QStringLiteral(
"angle" )].toDouble() );
3692 layer->restoreOldDataDefinedProperties(
properties );
3694 return layer.release();
3699 return QStringLiteral(
"PointPatternFill" );
3702void QgsPointPatternFillSymbolLayer::applyPattern(
const QgsSymbolRenderContext &context, QBrush &brush,
double distanceX,
double distanceY,
3703 double displacementX,
double displacementY,
double offsetX,
double offsetY )
3710 double widthOffset = std::fmod(
3713 double heightOffset = std::fmod(
3717 if ( width > 10000 || height > 10000 )
3720 brush.setTextureImage( img );
3724 QImage patternImage( width, height, QImage::Format_ARGB32 );
3725 patternImage.fill( 0 );
3726 if ( patternImage.isNull() )
3728 brush.setTextureImage( QImage() );
3733 QPainter p( &patternImage );
3751 for (
double currentX = -width; currentX <= width * 2.0; currentX += width )
3753 for (
double currentY = -height; currentY <= height * 2.0; currentY += height )
3755 mMarkerSymbol->renderPoint( QPointF( currentX + widthOffset, currentY + heightOffset ), context.
feature(), pointRenderContext );
3766 for (
double currentX = -width; currentX <= width * 2.0; currentX += width )
3768 for (
double currentY = -height / 2.0; currentY <= height * 2.0; currentY += height )
3770 mMarkerSymbol->renderPoint( QPointF( currentX + widthOffset + displacementPixelX, currentY + heightOffset ), context.
feature(), pointRenderContext );
3774 for (
double currentX = -width / 2.0; currentX <= width * 2.0; currentX += width )
3776 for (
double currentY = -height; currentY <= height * 2.0; currentY += height / 2.0 )
3778 mMarkerSymbol->renderPoint( QPointF( currentX + widthOffset + ( std::fmod( currentY, height ) != 0 ? displacementPixelX : 0 ), currentY + heightOffset - displacementPixelY ), context.
feature(), pointRenderContext );
3787 QImage transparentImage = patternImage.copy();
3789 brush.setTextureImage( transparentImage );
3793 brush.setTextureImage( patternImage );
3795 QTransform brushTransform;
3796 brush.setTransform( brushTransform );
3814 if ( mRenderUsingMarkers )
3827 if ( mRenderUsingMarkers )
3849 if ( !mRenderUsingMarkers )
3892 const double widthOffset = std::fmod(
3904 const double heightOffset = std::fmod(
3930 p->setPen( QPen( Qt::NoPen ) );
3935 p->setBrush( QBrush( selColor ) );
3959 std::unique_ptr< QgsPolygon > shapePolygon;
3960 std::unique_ptr< QgsGeometryEngine > shapeEngine;
3967 shapePolygon = std::make_unique< QgsPolygon >();
3971 for (
const QPolygonF &ring : *rings )
3977 shapeEngine->prepareGeometry();
3984 path.addPolygon( points );
3987 for (
const QPolygonF &ring : *rings )
3989 path.addPolygon( ring );
3992 p->setClipPath( path, Qt::IntersectClip );
3998 const QRectF boundingRect = points.boundingRect();
4000 QTransform invertedRotateTransform;
4008 QTransform transform;
4009 if ( applyBrushTransform )
4012 transform.translate( -boundingRect.center().x(),
4013 -boundingRect.center().y() );
4014 transform.rotate( -
angle );
4015 transform.translate( boundingRect.center().x(),
4016 boundingRect.center().y() );
4021 transform.rotate( -
angle );
4024 const QRectF transformedBounds = transform.map( points ).boundingRect();
4025 left = transformedBounds.left() - 2 * width;
4026 top = transformedBounds.top() - 2 * height;
4027 right = transformedBounds.right() + 2 * width;
4028 bottom = transformedBounds.bottom() + 2 * height;
4029 invertedRotateTransform = transform.inverted();
4031 if ( !applyBrushTransform )
4033 left -= transformedBounds.left() - ( width * std::floor( transformedBounds.left() / width ) );
4034 top -= transformedBounds.top() - ( height * std::floor( transformedBounds.top() / height ) );
4039 left = boundingRect.left() - 2 * width;
4040 top = boundingRect.top() - 2 * height;
4041 right = boundingRect.right() + 2 * width;
4042 bottom = boundingRect.bottom() + 2 * height;
4044 if ( !applyBrushTransform )
4046 left -= boundingRect.left() - ( width * std::floor( boundingRect.left() / width ) );
4047 top -= boundingRect.top() - ( height * std::floor( boundingRect.top() / height ) );
4076 std::random_device rd;
4077 std::mt19937 mt(
seed == 0 ? rd() :
seed );
4078 std::uniform_real_distribution<> uniformDist( 0, 1 );
4084 const bool needsExpressionContext =
mMarkerSymbol->hasDataDefinedProperties();
4092 bool alternateColumn =
false;
4093 int currentCol = -3;
4094 for (
double currentX = left; currentX <= right; currentX += width, alternateColumn = !alternateColumn )
4099 if ( needsExpressionContext )
4102 bool alternateRow =
false;
4103 const double columnX = currentX + widthOffset;
4104 int currentRow = -3;
4105 for (
double currentY = top; currentY <= bottom; currentY += height, alternateRow = !alternateRow )
4110 double y = currentY + heightOffset;
4113 x += displacementPixelX;
4115 if ( !alternateColumn )
4116 y -= displacementPixelY;
4122 invertedRotateTransform.map( xx, yy, &x, &y );
4125 if ( useRandomShift )
4127 x += ( 2 * uniformDist( mt ) - 1 ) * maxRandomDeviationPixelX;
4128 y += ( 2 * uniformDist( mt ) - 1 ) * maxRandomDeviationPixelY;
4131 if ( needsExpressionContext )
4139 bool renderPoint =
true;
4147 renderPoint = shapeEngine->intersects( &p );
4157 renderPoint = shapeEngine->contains( markerBounds.
constGet() );
4159 renderPoint = shapeEngine->intersects( markerBounds.
constGet() );
4185 map.insert( QStringLiteral(
"distance_x" ), QString::number(
mDistanceX ) );
4186 map.insert( QStringLiteral(
"distance_y" ), QString::number(
mDistanceY ) );
4187 map.insert( QStringLiteral(
"displacement_x" ), QString::number(
mDisplacementX ) );
4188 map.insert( QStringLiteral(
"displacement_y" ), QString::number(
mDisplacementY ) );
4189 map.insert( QStringLiteral(
"offset_x" ), QString::number(
mOffsetX ) );
4190 map.insert( QStringLiteral(
"offset_y" ), QString::number(
mOffsetY ) );
4206 map.insert( QStringLiteral(
"random_deviation_x" ), QString::number(
mRandomDeviationX ) );
4207 map.insert( QStringLiteral(
"random_deviation_y" ), QString::number(
mRandomDeviationY ) );
4212 map.insert( QStringLiteral(
"seed" ), QString::number(
mSeed ) );
4213 map.insert( QStringLiteral(
"angle" ),
mAngle );
4232 for (
int i = 0; i <
mMarkerSymbol->symbolLayerCount(); i++ )
4234 QDomElement symbolizerElem = doc.createElement( QStringLiteral(
"se:PolygonSymbolizer" ) );
4235 if ( !props.value( QStringLiteral(
"uom" ), QString() ).toString().isEmpty() )
4236 symbolizerElem.setAttribute( QStringLiteral(
"uom" ), props.value( QStringLiteral(
"uom" ), QString() ).toString() );
4237 element.appendChild( symbolizerElem );
4242 QDomElement fillElem = doc.createElement( QStringLiteral(
"se:Fill" ) );
4243 symbolizerElem.appendChild( fillElem );
4245 QDomElement graphicFillElem = doc.createElement( QStringLiteral(
"se:GraphicFill" ) );
4246 fillElem.appendChild( graphicFillElem );
4253 symbolizerElem.appendChild( distanceElem );
4258 markerLayer->writeSldMarker( doc, graphicFillElem, props );
4262 QString errorMsg = QStringLiteral(
"QgsMarkerSymbolLayer expected, %1 found. Skip it." ).arg( layer->
layerType() );
4263 graphicFillElem.appendChild( doc.createComment( errorMsg ) );
4267 QString errorMsg = QStringLiteral(
"Missing point pattern symbol layer. Skip it." );
4268 graphicFillElem.appendChild( doc.createComment( errorMsg ) );
4358 attributes.unite(
mMarkerSymbol->usedAttributes( context ) );
4396 std::unique_ptr< QgsCentroidFillSymbolLayer > sl = std::make_unique< QgsCentroidFillSymbolLayer >();
4398 if (
properties.contains( QStringLiteral(
"point_on_surface" ) ) )
4399 sl->setPointOnSurface(
properties[QStringLiteral(
"point_on_surface" )].toInt() != 0 );
4400 if (
properties.contains( QStringLiteral(
"point_on_all_parts" ) ) )
4401 sl->setPointOnAllParts(
properties[QStringLiteral(
"point_on_all_parts" )].toInt() != 0 );
4402 if (
properties.contains( QStringLiteral(
"clip_points" ) ) )
4403 sl->setClipPoints(
properties[QStringLiteral(
"clip_points" )].toInt() != 0 );
4404 if (
properties.contains( QStringLiteral(
"clip_on_current_part_only" ) ) )
4405 sl->setClipOnCurrentPartOnly(
properties[QStringLiteral(
"clip_on_current_part_only" )].toInt() != 0 );
4407 sl->restoreOldDataDefinedProperties(
properties );
4409 return sl.release();
4414 return QStringLiteral(
"CentroidFill" );
4441 part.exterior = points;
4443 part.rings = *rings;
4450 mCurrentParts << part;
4455 const double prevOpacity =
mMarker->opacity();
4458 mMarker->setOpacity( prevOpacity );
4465 mCurrentParts.clear();
4472 const double prevOpacity =
mMarker->opacity();
4475 render( context, mCurrentParts, feature,
false );
4477 mMarker->setOpacity( prevOpacity );
4480void QgsCentroidFillSymbolLayer::render(
QgsRenderContext &context,
const QVector<QgsCentroidFillSymbolLayer::Part> &parts,
const QgsFeature &feature,
bool selected )
4489 QVector< QgsGeometry > geometryParts;
4490 geometryParts.reserve( parts.size() );
4491 QPainterPath globalPath;
4494 int maxAreaPartIdx = 0;
4496 for (
int i = 0; i < parts.size(); i++ )
4498 const Part part = parts[i];
4501 if ( !geom.
isNull() && !part.rings.empty() )
4503 QgsPolygon *poly = qgsgeometry_cast< QgsPolygon * >( geom.
get() );
4507 int area = poly->
area();
4509 if ( area > maxArea )
4519 globalPath.addPolygon( part.exterior );
4520 for (
const QPolygonF &ring : part.rings )
4522 globalPath.addPolygon( ring );
4527 for (
int i = 0; i < parts.size(); i++ )
4532 const Part part = parts[i];
4540 path.addPolygon( part.exterior );
4541 for (
const QPolygonF &ring : part.rings )
4543 path.addPolygon( ring );
4552 context.
painter()->setClipPath( path );
4572 map[QStringLiteral(
"point_on_surface" )] = QString::number(
mPointOnSurface );
4573 map[QStringLiteral(
"point_on_all_parts" )] = QString::number(
mPointOnAllParts );
4574 map[QStringLiteral(
"clip_points" )] = QString::number(
mClipPoints );
4581 std::unique_ptr< QgsCentroidFillSymbolLayer > x = std::make_unique< QgsCentroidFillSymbolLayer >();
4584 x->setSubSymbol(
mMarker->clone() );
4599 mMarker->toSld( doc, element, props );
4610 std::unique_ptr< QgsMarkerSymbol > marker(
new QgsMarkerSymbol( layers ) );
4612 std::unique_ptr< QgsCentroidFillSymbolLayer > sl = std::make_unique< QgsCentroidFillSymbolLayer >();
4613 sl->setSubSymbol( marker.release() );
4614 sl->setPointOnAllParts(
false );
4615 return sl.release();
4642 attributes.unite(
mMarker->usedAttributes( context ) );
4665 mMarker->setOutputUnit( unit );
4682 return mMarker->usesMapUnits();
4691 mMarker->setMapUnitScale( scale );
4699 return mMarker->mapUnitScale();
4709 , mImageFilePath( imageFilePath )
4726 if (
properties.contains( QStringLiteral(
"imageFile" ) ) )
4728 imagePath =
properties[QStringLiteral(
"imageFile" )].toString();
4730 if (
properties.contains( QStringLiteral(
"coordinate_mode" ) ) )
4734 if (
properties.contains( QStringLiteral(
"alpha" ) ) )
4736 alpha =
properties[QStringLiteral(
"alpha" )].toDouble();
4738 if (
properties.contains( QStringLiteral(
"offset" ) ) )
4742 if (
properties.contains( QStringLiteral(
"angle" ) ) )
4746 if (
properties.contains( QStringLiteral(
"width" ) ) )
4750 std::unique_ptr< QgsRasterFillSymbolLayer > symbolLayer = std::make_unique< QgsRasterFillSymbolLayer >( imagePath );
4751 symbolLayer->setCoordinateMode( mode );
4752 symbolLayer->setOpacity( alpha );
4753 symbolLayer->setOffset(
offset );
4754 symbolLayer->setAngle(
angle );
4755 symbolLayer->setWidth(
width );
4756 if (
properties.contains( QStringLiteral(
"offset_unit" ) ) )
4760 if (
properties.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
4764 if (
properties.contains( QStringLiteral(
"width_unit" ) ) )
4768 if (
properties.contains( QStringLiteral(
"width_map_unit_scale" ) ) )
4773 symbolLayer->restoreOldDataDefinedProperties(
properties );
4775 return symbolLayer.release();
4780 QVariantMap::iterator it =
properties.find( QStringLiteral(
"imageFile" ) );
4784 it.value() = pathResolver.
writePath( it.value().toString() );
4786 it.value() = pathResolver.
readPath( it.value().toString() );
4798 return QStringLiteral(
"RasterFill" );
4809 QPointF
offset = mOffset;
4827 QRectF boundingRect = points.boundingRect();
4828 mBrush.setTransform(
mBrush.transform().translate( boundingRect.left() -
mBrush.transform().dx(),
4829 boundingRect.top() -
mBrush.transform().dy() ) );
4841 applyPattern(
mBrush, mImageFilePath, mWidth, mOpacity * context.
opacity(), context );
4852 map[QStringLiteral(
"imageFile" )] = mImageFilePath;
4853 map[QStringLiteral(
"coordinate_mode" )] = QString::number(
static_cast< int >( mCoordinateMode ) );
4854 map[QStringLiteral(
"alpha" )] = QString::number( mOpacity );
4858 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
4859 map[QStringLiteral(
"width" )] = QString::number( mWidth );
4867 std::unique_ptr< QgsRasterFillSymbolLayer > sl = std::make_unique< QgsRasterFillSymbolLayer >( mImageFilePath );
4868 sl->setCoordinateMode( mCoordinateMode );
4869 sl->setOpacity( mOpacity );
4870 sl->setOffset( mOffset );
4871 sl->setOffsetUnit( mOffsetUnit );
4872 sl->setOffsetMapUnitScale( mOffsetMapUnitScale );
4874 sl->setWidth( mWidth );
4875 sl->setWidthUnit( mWidthUnit );
4876 sl->setWidthMapUnitScale( mWidthMapUnitScale );
4879 return sl.release();
4884 return context.
convertToPainterUnits( std::max( std::fabs( mOffset.x() ), std::fabs( mOffset.y() ) ), mOffsetUnit, mOffsetMapUnitScale );
4907 mImageFilePath = imagePath;
4912 mCoordinateMode = mode;
4930 if ( !hasWidthExpression && !hasAngleExpression && !hasOpacityExpression && !hasFileExpression )
4936 if ( hasAngleExpression )
4944 if ( !hasWidthExpression && !hasOpacityExpression && !hasFileExpression )
4949 double width = mWidth;
4950 if ( hasWidthExpression )
4956 if ( hasOpacityExpression )
4961 QString file = mImageFilePath;
4962 if ( hasFileExpression )
4975void QgsRasterFillSymbolLayer::applyPattern( QBrush &brush,
const QString &imageFilePath,
const double width,
const double alpha,
const QgsSymbolRenderContext &context )
4988 if ( size.isEmpty() )
4991 size.setWidth( (
width * size.width() ) / 100.0 );
4994 if (
static_cast< int >( size.width() ) < 1 || 10000.0 < size.width() )
4998 size.setHeight( 0 );
5006 brush.setTextureImage( img );
5015 : mCountMethod( method )
5016 , mPointCount( pointCount )
5017 , mDensityArea( densityArea )
5028 const int pointCount =
properties.value( QStringLiteral(
"point_count" ), QStringLiteral(
"10" ) ).toInt();
5029 const double densityArea =
properties.value( QStringLiteral(
"density_area" ), QStringLiteral(
"250.0" ) ).toDouble();
5031 unsigned long seed = 0;
5032 if (
properties.contains( QStringLiteral(
"seed" ) ) )
5038 std::random_device rd;
5039 std::mt19937 mt(
seed == 0 ? rd() :
seed );
5040 std::uniform_int_distribution<> uniformDist( 1, 999999999 );
5041 seed = uniformDist( mt );
5046 if (
properties.contains( QStringLiteral(
"density_area_unit" ) ) )
5048 if (
properties.contains( QStringLiteral(
"density_area_unit_scale" ) ) )
5051 if (
properties.contains( QStringLiteral(
"clip_points" ) ) )
5053 sl->setClipPoints(
properties[QStringLiteral(
"clip_points" )].toInt() );
5056 return sl.release();
5061 return QStringLiteral(
"RandomMarkerFill" );
5066 mMarker->setColor(
color );
5072 return mMarker ? mMarker->color() :
mColor;
5088 part.exterior = points;
5090 part.rings = *rings;
5092 if ( mRenderingFeature )
5096 mFeatureSymbolOpacity = context.
opacity();
5097 mCurrentParts << part;
5102 const double prevOpacity = mMarker->opacity();
5103 mMarker->setOpacity( mMarker->opacity() * context.
opacity() );
5105 mMarker->setOpacity( prevOpacity );
5109void QgsRandomMarkerFillSymbolLayer::render(
QgsRenderContext &context,
const QVector<QgsRandomMarkerFillSymbolLayer::Part> &parts,
const QgsFeature &feature,
bool selected )
5118 QVector< QgsGeometry > geometryParts;
5119 geometryParts.reserve( parts.size() );
5122 for (
const Part &part : parts )
5125 if ( !geom.
isNull() && !part.rings.empty() )
5127 QgsPolygon *poly = qgsgeometry_cast< QgsPolygon * >( geom.
get() );
5128 for (
const QPolygonF &ring : part.rings )
5135 geom = geom.
buffer( 0, 0 );
5137 geometryParts << geom;
5141 path.addPolygon( part.exterior );
5142 for (
const QPolygonF &ring : part.rings )
5144 path.addPolygon( ring );
5154 context.
painter()->setClipPath( path );
5158 int count = mPointCount;
5165 switch ( mCountMethod )
5167 case Qgis::PointCountMethod::DensityBased:
5177 count = std::max( 0.0, std::ceil( count * ( geom.
area() /
densityArea ) ) );
5180 case Qgis::PointCountMethod::Absolute:
5184 unsigned long seed = mSeed;
5195 std::sort( randomPoints.begin(), randomPoints.end(), [](
const QgsPointXY & a,
const QgsPointXY & b )->bool
5197 return a.y() < b.y();
5203 const bool needsExpressionContext = mMarker->hasDataDefinedProperties();
5208 for (
const QgsPointXY &p : std::as_const( randomPoints ) )
5210 if ( needsExpressionContext )
5212 mMarker->renderPoint( QPointF( p.x(), p.y() ), feature.
isValid() ? &feature :
nullptr, context, -1, selected );
5226 map.insert( QStringLiteral(
"count_method" ), QString::number(
static_cast< int >( mCountMethod ) ) );
5227 map.insert( QStringLiteral(
"point_count" ), QString::number( mPointCount ) );
5228 map.insert( QStringLiteral(
"density_area" ), QString::number( mDensityArea ) );
5231 map.insert( QStringLiteral(
"seed" ), QString::number( mSeed ) );
5232 map.insert( QStringLiteral(
"clip_points" ), QString::number( mClipPoints ) );
5238 std::unique_ptr< QgsRandomMarkerFillSymbolLayer > res = std::make_unique< QgsRandomMarkerFillSymbolLayer >( mPointCount, mCountMethod, mDensityArea, mSeed );
5241 res->setDensityAreaUnit( mDensityAreaUnit );
5242 res->setDensityAreaUnitScale( mDensityAreaUnitScale );
5243 res->mClipPoints = mClipPoints;
5244 res->setSubSymbol( mMarker->clone() );
5247 return res.release();
5257 return mMarker.get();
5269 mColor = mMarker->color();
5278 attributes.unite( mMarker->usedAttributes( context ) );
5287 if ( mMarker && mMarker->hasDataDefinedProperties() )
5324 return mCountMethod;
5329 mCountMethod = method;
5334 return mDensityArea;
5339 mDensityArea = area;
5344 mRenderingFeature =
true;
5345 mCurrentParts.clear();
5350 mRenderingFeature =
false;
5352 const double prevOpacity = mMarker->opacity();
5353 mMarker->setOpacity( mMarker->opacity() * mFeatureSymbolOpacity );
5355 render( context, mCurrentParts, feature,
false );
5357 mFeatureSymbolOpacity = 1;
5358 mMarker->setOpacity( prevOpacity );
5364 mDensityAreaUnit = unit;
5367 mMarker->setOutputUnit( unit );
5375 return mMarker->outputUnit();
5384 return mMarker->usesMapUnits();
5393 mMarker->setMapUnitScale( scale );
5401 return mMarker->mapUnitScale();
MarkerClipMode
Marker clipping modes.
@ CompletelyWithin
Render complete markers wherever the completely fall within the polygon shape.
@ NoClipping
No clipping, render complete markers.
@ Shape
Clip to polygon shape.
@ CentroidWithin
Render complete markers wherever their centroid falls within the polygon shape.
LineClipMode
Line clipping modes.
@ NoClipping
Lines are not clipped, will extend to shape's bounding box.
@ ClipPainterOnly
Applying clipping on the painter only (i.e. line endpoints will coincide with polygon bounding box,...
@ ClipToIntersection
Clip lines to intersection with polygon shape (slower) (i.e. line endpoints will coincide with polygo...
GradientColorSource
Gradient color sources.
@ ColorRamp
Gradient color ramp.
@ SimpleTwoColor
Simple two color gradient.
GradientSpread
Gradient spread options, which control how gradients are rendered outside of their start and end poin...
@ Reflect
Reflect gradient.
@ Pad
Pad out gradient using colors at endpoint of gradient.
PointCountMethod
Methods which define the number of points randomly filling a polygon.
@ RenderingSubSymbol
Set whenever a sub-symbol of a parent symbol is currently being rendered. Can be used during symbol a...
@ RenderBlocking
Render and load remote sources in the same thread to ensure rendering remote sources (svg and images)...
GradientType
Gradient types.
@ Conical
Conical (polar) gradient.
@ Radial
Radial (circular) gradient.
SymbolCoordinateReference
Symbol coordinate reference modes.
@ Feature
Relative to feature/shape being rendered.
@ Viewport
Relative to the whole viewport/output device.
QColor valueAsColor(int key, const QgsExpressionContext &context, const QColor &defaultColor=QColor(), bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a color.
int valueAsInt(int key, const QgsExpressionContext &context, int defaultValue=0, bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as an integer.
bool valueAsBool(int key, const QgsExpressionContext &context, bool defaultValue=false, bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as an boolean.
double valueAsDouble(int key, const QgsExpressionContext &context, double defaultValue=0.0, bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a double.
QString valueAsString(int key, const QgsExpressionContext &context, const QString &defaultString=QString(), bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a string.
static QgsImageCache * imageCache()
Returns the application's image cache, used for caching resampled versions of raster images.
static QgsSvgCache * svgCache()
Returns the application's SVG cache, used for caching SVG images and handling parameter replacement w...
static QgsSymbolLayer * createFromSld(QDomElement &element)
void setOutputUnit(QgsUnitTypes::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.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
QgsSymbol * subSymbol() override
Returns the symbol's sub symbol, if present.
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer's subsymbol. takes ownership of the passed symbol.
void setMapUnitScale(const QgsMapUnitScale &scale) override
bool canCauseArtifactsBetweenAdjacentTiles() const override
Returns true if the symbol layer rendering can cause visible artifacts across a single feature when t...
bool pointOnSurface() const
QgsMapUnitScale mapUnitScale() const override
void startFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called before the layer will be rendered for a particular feature.
std::unique_ptr< QgsMarkerSymbol > mMarker
QString layerType() const override
Returns a string that represents this layer type.
void setColor(const QColor &color) override
Sets the "representative" color for the symbol layer.
bool pointOnAllParts() const
Returns whether a point is drawn for all parts or only on the biggest part of multi-part features.
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
bool hasDataDefinedProperties() const override
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
void stopFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called after the layer has been rendered for a particular feature.
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...
QgsUnitTypes::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
~QgsCentroidFillSymbolLayer() override
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
double mFeatureSymbolOpacity
QgsCentroidFillSymbolLayer()
QColor color() const override
Returns the "representative" color of the symbol layer.
bool clipOnCurrentPartOnly() const
Returns true if point markers should be clipped to the current part boundary only.
bool mClipOnCurrentPartOnly
Abstract base class for color ramps.
virtual QColor color(double value) const =0
Returns the color corresponding to a specified value.
virtual QVariantMap properties() const =0
Returns a string map containing all the color ramp's properties.
virtual QgsColorRamp * clone() const =0
Creates a clone of the color ramp.
virtual QString type() const =0
Returns a string representing the color ramp type.
static QgsColorRamp * create(const QVariantMap &properties=QVariantMap())
Creates the symbol layer.
static QString typeString()
Returns the string identifier for QgsCptCityColorRamp.
double area() const override SIP_HOLDGIL
Returns the planar, 2-dimensional area of the geometry.
Exports QGIS layers to the DXF format.
static double mapUnitScaleFactor(double scale, QgsUnitTypes::RenderUnit symbolUnits, QgsUnitTypes::DistanceUnit mapUnits, double mapUnitsPerPixel=1.0)
Returns scale factor for conversion to map units.
QgsUnitTypes::DistanceUnit mapUnits() const
Retrieve map units.
double symbologyScale() const
Returns the reference scale for output.
RAII class to pop scope from an expression context on destruction.
Single scope for storing variables and functions for use within a QgsExpressionContext.
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
static const QString EXPR_GEOMETRY_POINT_NUM
Inbuilt variable name for point number variable.
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for the context.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
bool isValid() const
Returns the validity of this feature.
bool isCanceled() const SIP_HOLDGIL
Tells whether the operation has been canceled already.
void _renderPolygon(QPainter *p, const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context)
Default method to render polygon.
A geometry is the spatial representation of a feature.
QVector< QgsPointXY > randomPointsInPolygon(int count, const std::function< bool(const QgsPointXY &) > &acceptPoint, unsigned long seed=0, QgsFeedback *feedback=nullptr, int maxTriesPerPoint=0) const
Returns a list of count random points generated inside a (multi)polygon geometry (if acceptPoint is s...
const QgsAbstractGeometry * constGet() const SIP_HOLDGIL
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
static QgsGeometry fromQPolygonF(const QPolygonF &polygon)
Construct geometry from a QPolygonF.
QgsAbstractGeometry * get()
Returns a modifiable (non-const) reference to the underlying abstract geometry primitive.
static QgsGeometry fromRect(const QgsRectangle &rect) SIP_HOLDGIL
Creates a new geometry from a QgsRectangle.
bool isGeosValid(Qgis::GeometryValidityFlags flags=Qgis::GeometryValidityFlags()) const
Checks validity of the geometry using GEOS.
double area() const
Returns the planar, 2-dimensional area of the geometry.
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometry *geometry)
Creates and returns a new geometry engine representing the specified geometry.
QgsGeometry buffer(double distance, int segments) const
Returns a buffer region around this geometry having the given width and with a specified number of se...
static QgsGeometry unaryUnion(const QVector< QgsGeometry > &geometries, const QgsGeometryParameters ¶meters=QgsGeometryParameters())
Compute the unary union on a list of geometries.
Gradient color ramp, which smoothly interpolates between two colors and also supports optional extra ...
static QgsColorRamp * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsColorRamp from a map of properties.
static QString typeString()
Returns the string identifier for QgsGradientColorRamp.
void addStopsToGradient(QGradient *gradient, double opacity=1) const
Copy color ramp stops to a QGradient.
void setColorRamp(QgsColorRamp *ramp)
Sets the color ramp used for the gradient fill.
void setOutputUnit(QgsUnitTypes::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QgsUnitTypes::RenderUnit mOffsetUnit
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
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
QgsUnitTypes::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
Qgis::GradientColorSource gradientColorType() const
Returns the gradient color mode, which controls how gradient color stops are created.
QPointF offset() const
Returns the offset by which polygons will be translated during rendering.
Qgis::GradientColorSource mGradientColorType
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
QString layerType() const override
Returns a string that represents this layer type.
Qgis::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()
QgsUnitTypes::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
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.
void setOutputUnit(QgsUnitTypes::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QgsMapUnitScale mapUnitScale() const override
Qt::PenStyle dxfPenStyle() const override
Gets pen style.
void setMapUnitScale(const QgsMapUnitScale &scale) override
virtual void applyDataDefinedSettings(QgsSymbolRenderContext &context)
Applies data defined settings prior to generating the fill symbol brush.
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,...
QgsUnitTypes::RenderUnit mStrokeWidthUnit
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.
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.
QgsUnitTypes::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
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 setOutputUnit(QgsUnitTypes::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
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.
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.
QString ogrFeatureStyleWidth(double widthScaleFactor) const
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
~QgsLinePatternFillSymbolLayer() override
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
static QgsSymbolLayer * createFromSld(QDomElement &element)
Creates a new QgsLinePatternFillSymbolLayer from a SLD element.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsLinePatternFillSymbolLayer from a properties map.
Line string geometry type, with support for z-dimension and m-values.
QPolygonF asQPolygonF() const override
Returns a QPolygonF representing the points.
static QgsLineString * fromQPolygonF(const QPolygonF &polygon)
Returns a new linestring from a QPolygonF polygon input.
A line symbol type, for rendering LineString and MultiLineString geometries.
Perform transforms between map coordinates and device coordinates.
double mapUnitsPerPixel() const
Returns the current map units per pixel.
Struct for storing maximum and minimum scales for measurements in map units.
Line symbol layer type which draws repeating marker symbols along a line feature.
Abstract base class for marker symbol layers.
A marker symbol type, for rendering Point and MultiPoint geometries.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
Resolves relative paths into absolute paths and vice versa.
QString writePath(const QString &filename) const
Prepare a filename to save it to the project file.
QString readPath(const QString &filename) const
Turn filename read from the project file to an absolute path.
A fill symbol layer which fills polygon shapes with repeating marker symbols.
QgsMapUnitScale mapUnitScale() const override
QgsUnitTypes::RenderUnit mRandomDeviationYUnit
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,...
void setOutputUnit(QgsUnitTypes::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
double distanceX() const
Returns the horizontal distance between rendered markers in the fill.
QgsMapUnitScale mDistanceYMapUnitScale
QgsUnitTypes::RenderUnit mDisplacementXUnit
double displacementY() const
Returns the vertical displacement for odd numbered columns in the pattern.
QgsUnitTypes::RenderUnit mDistanceYUnit
void setColor(const QColor &c) override
Sets the "representative" color for the symbol layer.
QgsUnitTypes::RenderUnit mOffsetXUnit
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::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.
QgsUnitTypes::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
QgsUnitTypes::RenderUnit mRandomDeviationXUnit
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.
QColor color() const override
Returns the "representative" color of the symbol layer.
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.
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
QgsUnitTypes::RenderUnit mDistanceXUnit
QgsUnitTypes::RenderUnit mOffsetYUnit
double displacementX() const
Returns the horizontal displacement for odd numbered rows in the pattern.
double angle() const
Returns the rotation angle of the pattern, in degrees clockwise.
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.
QgsUnitTypes::RenderUnit mDisplacementYUnit
void setClipMode(Qgis::MarkerClipMode mode)
Sets the marker clipping mode, which defines how markers are clipped at the edges of shapes.
static QgsSymbolLayer * createFromSld(QDomElement &element)
A class to represent a 2D point.
Point geometry type, with support for z-dimension and m-values.
void addInteriorRing(QgsCurve *ring) override
Adds an interior ring to the geometry (takes ownership)
QVariant value(int key, const QgsExpressionContext &context, const QVariant &defaultValue=QVariant()) const override
Returns the calculated value of the property with the specified key from within the collection.
bool isActive(int key) const override
Returns true if the collection contains an active property with the specified key.
static QVariantMap propertyMapToVariantMap(const QMap< QString, QgsProperty > &propertyMap)
Convert a map of QgsProperty to a map of QVariant This is useful to save a map of properties.
static QMap< QString, QgsProperty > variantMapToPropertyMap(const QVariantMap &variantMap)
Convert a map of QVariant to a map of QgsProperty This is useful to restore a map of properties.
A fill symbol layer which places markers at random locations within polygons.
~QgsRandomMarkerFillSymbolLayer() override
int pointCount() const
Returns the count of random points to render in the fill.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
void startFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called before the layer will be rendered for a particular feature.
QgsRandomMarkerFillSymbolLayer(int pointCount=10, Qgis::PointCountMethod method=Qgis::PointCountMethod::Absolute, double densityArea=250.0, unsigned long seed=0)
Constructor for QgsRandomMarkerFillSymbolLayer, with the specified pointCount.
unsigned long seed() const
Returns the random number seed to use when generating points, or 0 if a truly random sequence will be...
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsRandomMarkerFillSymbolLayer using the specified properties map containing symbol pro...
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
void setOutputUnit(QgsUnitTypes::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
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.
void setMapUnitScale(const QgsMapUnitScale &scale) override
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer's subsymbol. takes ownership of the passed symbol.
bool hasDataDefinedProperties() const override
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
void stopFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called after the layer has been rendered for a particular feature.
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
void setCountMethod(Qgis::PointCountMethod method)
Sets the count method used to randomly fill the polygon.
bool clipPoints() const
Returns true if point markers should be clipped to the polygon boundary.
QgsUnitTypes::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
bool canCauseArtifactsBetweenAdjacentTiles() const override
Returns true if the symbol layer rendering can cause visible artifacts across a single feature when t...
void setClipPoints(bool clipped)
Sets whether point markers should be clipped to the polygon boundary.
QgsSymbol * subSymbol() override
Returns the symbol's sub symbol, if present.
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
QColor color() const override
Returns the "representative" color of the symbol layer.
void setSeed(unsigned long seed)
Sets the random number seed to use when generating points, or 0 if a truly random sequence will be us...
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
void setPointCount(int count)
Sets the count of random points to render in the fill.
Qgis::PointCountMethod countMethod() const
Returns the count method used to randomly fill the polygon.
double densityArea() const
Returns the density area used to count the number of points to randomly fill the polygon.
void setColor(const QColor &color) override
Sets the "representative" color for the symbol layer.
void setDensityArea(double area)
Sets the density area used to count the number of points to randomly fill the polygon.
QgsMapUnitScale mapUnitScale() const override
A class for filling symbols with a repeated raster image.
void applyDataDefinedSettings(QgsSymbolRenderContext &context) override
Applies data defined settings prior to generating the fill symbol brush.
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
double width() const
Returns the width used for scaling the image used in the fill.
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
static QgsSymbolLayer * 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.
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 setOutputUnit(QgsUnitTypes::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
void setOpacity(double opacity)
Sets the opacity for the raster image used in the fill.
QColor color() const override
Returns the "representative" color of the symbol layer.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
QString imageFilePath() const
The path to the raster image used for the fill.
void setImageFilePath(const QString &imagePath)
Sets the path to the raster image used for the fill.
static void resolvePaths(QVariantMap &properties, const QgsPathResolver &pathResolver, bool saving)
Turns relative paths in properties map to absolute when reading and vice versa when writing.
QPointF offset() const
Returns the offset for the fill.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer's subsymbol. takes ownership of the passed symbol.
QgsRasterFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
bool applyBrushTransformFromContext(QgsSymbolRenderContext *context=nullptr) const override
Returns true if the image brush should be transformed using the render context's texture origin.
void setCoordinateMode(Qgis::SymbolCoordinateReference mode)
Set the coordinate mode for fill.
A rectangle specified with double values.
QgsPointXY center() const SIP_HOLDGIL
Returns the center point of the rectangle.
Contains information about the context of a rendering operation.
void setForceVectorOutput(bool force)
Sets whether rendering operations should use vector operations instead of any faster raster shortcuts...
double scaleFactor() const
Returns the scaling factor for the render to convert painter units to physical sizes.
void setScaleFactor(double factor)
Sets the scaling factor for the render to convert painter units to physical sizes.
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 ...
double convertToPainterUnits(double size, QgsUnitTypes::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale(), Qgis::RenderSubcomponentProperty property=Qgis::RenderSubcomponentProperty::Generic) const
Converts a size from the specified units to painter units (pixels).
QgsExpressionContext & expressionContext()
Gets the expression context.
bool forceVectorOutput() const
Returns true if rendering operations should use vector operations instead of any faster raster shortc...
void 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...
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.
void setOutputUnit(QgsUnitTypes::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
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.
QgsUnitTypes::RenderUnit svgStrokeWidthUnit() const
Returns the units for the stroke width.
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.
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.
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
QgsUnitTypes::RenderUnit patternWidthUnit() const
Returns the units for the width of the SVG images in the pattern.
void setMapUnitScale(const QgsMapUnitScale &scale) override
QgsUnitTypes::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
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
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 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...
QPointF offset() const
Returns the offset for the shapeburst fill.
bool useWholeShape() const
Returns whether the shapeburst fill is set to cover the entire shape.
bool ignoreRings() const
Returns whether the shapeburst fill is set to ignore polygon interior rings.
double maxDistance() const
Returns the maximum distance from the shape's boundary which is shaded.
QString layerType() const override
Returns a string that represents this layer type.
void setOutputUnit(QgsUnitTypes::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
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 ...
QgsUnitTypes::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
void setColorRamp(QgsColorRamp *ramp)
Sets the color ramp used to draw the shapeburst fill.
QgsSimpleFillSymbolLayer(const QColor &color=DEFAULT_SIMPLEFILL_COLOR, Qt::BrushStyle style=DEFAULT_SIMPLEFILL_STYLE, const QColor &strokeColor=DEFAULT_SIMPLEFILL_BORDERCOLOR, Qt::PenStyle strokeStyle=DEFAULT_SIMPLEFILL_BORDERSTYLE, double strokeWidth=DEFAULT_SIMPLEFILL_BORDERWIDTH, Qt::PenJoinStyle penJoinStyle=DEFAULT_SIMPLEFILL_JOINSTYLE)
double dxfWidth(const QgsDxfExport &e, QgsSymbolRenderContext &context) const override
Gets line width.
Qt::PenJoinStyle penJoinStyle() const
QColor strokeColor() const override
Returns the stroke color for the symbol layer.
QColor dxfBrushColor(QgsSymbolRenderContext &context) const override
Gets brush/fill color.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
Qt::BrushStyle dxfBrushStyle() const override
Gets brush/fill style.
QString ogrFeatureStyle(double mmScaleFactor, double mapUnitScaleFactor) const override
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
QgsUnitTypes::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 ...
QgsUnitTypes::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
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.
QgsMapUnitScale mOffsetMapUnitScale
double strokeWidth() const
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
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
Qt::PenJoinStyle mPenJoinStyle
Qt::BrushStyle mBrushStyle
void setOutputUnit(QgsUnitTypes::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
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)
QgsUnitTypes::RenderUnit mStrokeWidthUnit
QByteArray getImageData(const QString &path, bool blocking=false) const
Gets the SVG content corresponding to the given path.
QPicture svgAsPicture(const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth, double widthScaleFactor, bool forceVectorOutput=false, double fixedAspectRatio=0, bool blocking=false, const QMap< QString, QString > ¶meters=QMap< QString, QString >())
Returns an SVG drawing as a QPicture.
void containsParams(const QString &path, bool &hasFillParam, QColor &defaultFillColor, bool &hasStrokeParam, QColor &defaultStrokeColor, bool &hasStrokeWidthParam, double &defaultStrokeWidth, bool blocking=false) const
Tests if an SVG file contains parameters for fill, stroke color, stroke width.
QImage svgAsImage(const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth, double widthScaleFactor, bool &fitsInCache, double fixedAspectRatio=0, bool blocking=false, const QMap< QString, QString > ¶meters=QMap< QString, QString >())
Returns an SVG drawing as a QImage.
static bool rotationFromSldElement(QDomElement &element, QString &rotationFunc)
static Qgis::MarkerClipMode decodeMarkerClipMode(const QString &string, bool *ok=nullptr)
Decodes a string representing a marker clip mode.
static QString encodePenStyle(Qt::PenStyle style)
static Qt::PenJoinStyle decodePenJoinStyle(const QString &str)
static QString encodeMapUnitScale(const QgsMapUnitScale &mapUnitScale)
static QgsStringMap evaluatePropertiesMap(const QMap< QString, QgsProperty > &propertiesMap, const QgsExpressionContext &context)
Evaluates a map of properties using the given context and returns a variant map with evaluated expres...
static bool displacementFromSldElement(QDomElement &element, QPointF &offset)
static QColor decodeColor(const QString &str)
static QPointF polygonCentroid(const QPolygonF &points)
Calculate the centroid point of a QPolygonF.
static QString encodeBrushStyle(Qt::BrushStyle style)
static QString svgSymbolPathToName(const QString &path, const QgsPathResolver &pathResolver)
Determines an SVG symbol's name from its path.
static 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 double rescaleUom(double size, QgsUnitTypes::RenderUnit unit, const QVariantMap &props)
Rescales the given size based on the uomScale found in the props, if any is found,...
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 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 QgsUnitTypes::RenderUnit decodeSldUom(const QString &str, double *scaleFactor=nullptr)
Decodes a SLD unit of measure string to a render unit.
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 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 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 QPointF decodePoint(const QString &string)
Decodes a QSizeF from a string.
static QgsSymbolLayer * createLineLayerFromSld(QDomElement &element)
static QString encodeCoordinateReference(Qgis::SymbolCoordinateReference coordinateReference)
Encodes a symbol coordinate reference mode to a string.
static QString encodeMarkerClipMode(Qgis::MarkerClipMode mode)
Encodes a marker clip mode to a string.
@ PropertyGradientReference1X
Gradient reference point 1 x.
@ PropertyShapeburstIgnoreRings
Shapeburst ignore rings.
@ PropertyGradientReference2X
Gradient reference point 2 x.
@ PropertyStrokeStyle
Stroke style (eg solid, dashed)
@ PropertyDistanceX
Horizontal distance between points.
@ PropertyFile
Filename, eg for svg files.
@ PropertyGradientType
Gradient fill type.
@ PropertyAngle
Symbol angle.
@ PropertyLineClipping
Line clipping mode (since QGIS 3.24)
@ PropertyDistanceY
Vertical distance between points.
@ PropertyDisplacementX
Horizontal displacement.
@ PropertyGradientSpread
Gradient spread mode.
@ PropertyOffsetY
Vertical offset.
@ PropertyGradientReference1Y
Gradient reference point 1 y.
@ PropertyLineDistance
Distance between lines, or length of lines for hash line symbols.
@ PropertyBlurRadius
Shapeburst blur radius.
@ PropertyGradientReference2Y
Gradient reference point 2 y.
@ PropertyMarkerClipping
Marker clipping mode (since QGIS 3.24)
@ PropertyDensityArea
Density area.
@ PropertyGradientReference1IsCentroid
Gradient reference point 1 is centroid.
@ PropertyShapeburstUseWholeShape
Shapeburst use whole shape.
@ PropertyOffsetX
Horizontal offset.
@ PropertyJoinStyle
Line join style.
@ PropertyOpacity
Opacity.
@ PropertySecondaryColor
Secondary color (eg for gradient fills)
@ PropertyCoordinateMode
Gradient coordinate mode.
@ PropertyRandomOffsetY
Random offset Y (since QGIS 3.24)
@ PropertyLineAngle
Line angle, or angle of hash lines for hash line symbols.
@ PropertyShapeburstMaxDistance
Shapeburst fill from edge distance.
@ PropertyOffset
Symbol offset.
@ PropertyStrokeWidth
Stroke width.
@ PropertyFillColor
Fill color.
@ PropertyClipPoints
Whether markers should be clipped to polygon boundaries.
@ PropertyPointCount
Point count.
@ PropertyRandomSeed
Random number seed.
@ PropertyRandomOffsetX
Random offset X (since QGIS 3.24)
@ PropertyFillStyle
Fill style (eg solid, dots)
@ PropertyDisplacementY
Vertical displacement.
@ PropertyStrokeColor
Stroke color.
@ PropertyGradientReference2IsCentroid
Gradient reference point 2 is centroid.
@ PropertyWidth
Symbol width.
virtual bool setSubSymbol(QgsSymbol *symbol)
Sets layer's subsymbol. takes ownership of the passed symbol.
Qgis::SymbolType type() const
virtual QColor fillColor() const
Returns the fill color for the symbol layer.
static const bool SELECTION_IS_OPAQUE
Whether styles for selected features ignore symbol alpha.
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.
virtual double estimateMaxBleed(const QgsRenderContext &context) const
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
static const bool SELECT_FILL_BORDER
Whether fill styles for selected features also highlight symbol stroke.
virtual QString layerType() const =0
Returns a string that represents this layer type.
virtual QColor color() const
Returns the "representative" color of the symbol layer.
virtual QColor strokeColor() const
Returns the stroke color for the symbol layer.
void copyPaintEffect(QgsSymbolLayer *destLayer) const
Copies paint effect of this layer to another symbol layer.
QgsPropertyCollection mDataDefinedProperties
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the symbol layer's property collection, used for data defined overrides.
static const bool SELECT_FILL_STYLE
Whether fill styles for selected features uses symbol layer style.
virtual bool hasDataDefinedProperties() const
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
const QgsFeature * feature() const
Returns the current feature being rendered.
QgsFields fields() const
Fields of the layer.
bool selected() const
Returns true if symbols should be rendered using the selected symbol coloring and style.
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for data defined symbology.
qreal opacity() const
Returns the opacity for the symbol.
QgsRenderContext & renderContext()
Returns a reference to the context's render context.
Abstract base class for all rendered symbols.
Qgis::SymbolType type() const
Returns the symbol's type.
double interval() const
Returns the interval between individual symbols.
const QgsMapUnitScale & intervalMapUnitScale() const
Returns the map unit scale for the interval between symbols.
void setInterval(double interval)
Sets the interval between individual symbols.
QgsUnitTypes::RenderUnit intervalUnit() const
Returns the units for the interval between symbols.
static Q_INVOKABLE QString encodeUnit(QgsUnitTypes::DistanceUnit unit)
Encodes a distance unit to a string.
static Q_INVOKABLE QgsUnitTypes::RenderUnit decodeRenderUnit(const QString &string, bool *ok=nullptr)
Decodes a render unit from a string.
RenderUnit
Rendering size units.
@ RenderUnknownUnit
Mixed or unknown units.
@ RenderMetersInMapUnits
Meters value as Map units.
@ RenderPercentage
Percentage of another measurement (e.g., canvas size, feature size)
@ RenderMapUnits
Map units.
static bool isNull(const QVariant &variant)
Returns true if the specified variant should be considered a NULL value.
double ANALYSIS_EXPORT angle(QgsPoint *p1, QgsPoint *p2, QgsPoint *p3, QgsPoint *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
CORE_EXPORT QgsMeshVertex centroid(const QgsMeshFace &face, const QVector< QgsMeshVertex > &vertices)
Returns the centroid of the face.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
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.