46#include <QDomDocument>
49#include <QPagedPaintDevice>
51#include <QSvgRenderer>
104void QgsSimpleFillSymbolLayer::applyDataDefinedSymbology(
QgsSymbolRenderContext &context, QBrush &brush, QPen &pen, QPen &selPen )
129 penColor.setAlphaF( context.
opacity() * penColor.alphaF() );
130 pen.setColor( penColor );
138 double width = exprVal.toDouble( &ok );
142 pen.setWidthF( width );
143 selPen.setWidthF( width );
180 if ( props.contains( QStringLiteral(
"color" ) ) )
182 if ( props.contains( QStringLiteral(
"style" ) ) )
184 if ( props.contains( QStringLiteral(
"color_border" ) ) )
189 else if ( props.contains( QStringLiteral(
"outline_color" ) ) )
193 else if ( props.contains( QStringLiteral(
"line_color" ) ) )
198 if ( props.contains( QStringLiteral(
"style_border" ) ) )
203 else if ( props.contains( QStringLiteral(
"outline_style" ) ) )
207 else if ( props.contains( QStringLiteral(
"line_style" ) ) )
211 if ( props.contains( QStringLiteral(
"width_border" ) ) )
214 strokeWidth = props[QStringLiteral(
"width_border" )].toDouble();
216 else if ( props.contains( QStringLiteral(
"outline_width" ) ) )
218 strokeWidth = props[QStringLiteral(
"outline_width" )].toDouble();
220 else if ( props.contains( QStringLiteral(
"line_width" ) ) )
222 strokeWidth = props[QStringLiteral(
"line_width" )].toDouble();
224 if ( props.contains( QStringLiteral(
"offset" ) ) )
226 if ( props.contains( QStringLiteral(
"joinstyle" ) ) )
231 if ( props.contains( QStringLiteral(
"border_width_unit" ) ) )
235 else if ( props.contains( QStringLiteral(
"outline_width_unit" ) ) )
239 else if ( props.contains( QStringLiteral(
"line_width_unit" ) ) )
243 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
246 if ( props.contains( QStringLiteral(
"border_width_map_unit_scale" ) ) )
248 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
251 sl->restoreOldDataDefinedProperties( props );
259 return QStringLiteral(
"SimpleFill" );
276 selColor.setAlphaF( context.
opacity() );
335 if (
mBrush.style() == Qt::SolidPattern ||
mBrush.style() == Qt::NoBrush || !
dynamic_cast<QPagedPaintDevice *
>( p->device() ) )
347 p->setPen( Qt::NoPen );
351 p->setBrush( Qt::NoBrush );
368 map[QStringLiteral(
"outline_width" )] = QString::number(
mStrokeWidth );
395 toSld( doc, element, context );
404 QDomElement symbolizerElem = doc.createElement( QStringLiteral(
"se:PolygonSymbolizer" ) );
405 if ( !props.value( QStringLiteral(
"uom" ), QString() ).toString().isEmpty() )
406 symbolizerElem.setAttribute( QStringLiteral(
"uom" ), props.value( QStringLiteral(
"uom" ), QString() ).toString() );
407 element.appendChild( symbolizerElem );
413 bool exportOk {
false };
417 if ( ! image.isNull() )
420 QDomElement fillElem = doc.createElement( QStringLiteral(
"se:Fill" ) );
421 symbolizerElem.appendChild( fillElem );
422 QDomElement graphicFillElem = doc.createElement( QStringLiteral(
"se:GraphicFill" ) );
423 fillElem.appendChild( graphicFillElem );
424 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
425 graphicFillElem.appendChild( graphicElem );
428 QString pngPath { info.completeSuffix().isEmpty() ? context.
exportFilePath() : context.
exportFilePath().chopped( info.completeSuffix().length() ).append( QStringLiteral(
"png" ) ) };
429 pngPath = QgsFileUtils::uniquePath( pngPath );
430 image.save( pngPath );
445 const double alpha { props.value( QStringLiteral(
"alpha" ), QVariant() ).toDouble( &ok ) };
451 QDomElement fillElem = doc.createElement( QStringLiteral(
"se:Fill" ) );
452 symbolizerElem.appendChild( fillElem );
459 QDomElement strokeElem = doc.createElement( QStringLiteral(
"se:Stroke" ) );
460 symbolizerElem.appendChild( strokeElem );
464 const double alpha { props.value( QStringLiteral(
"alpha" ), QVariant() ).toDouble( &ok ) };
485 symbolStyle.append(
';' );
494 Qt::BrushStyle fillStyle;
498 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
501 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
507 double scaleFactor = 1.0;
508 const QString uom = element.attribute( QStringLiteral(
"uom" ) );
515 sl->setOutputUnit( sldUnitSize );
524 return penBleed + offsetBleed;
582 QPixmap pixmap( QSize( 32, 32 ) );
583 pixmap.fill( Qt::transparent );
585 painter.begin( &pixmap );
586 painter.setRenderHint( QPainter::Antialiasing );
594 std::unique_ptr< QgsSimpleFillSymbolLayer > layerClone(
clone() );
595 layerClone->setStrokeStyle( Qt::PenStyle::NoPen );
596 layerClone->drawPreviewIcon( symbolContext, pixmap.size() );
598 return pixmap.toImage();
632 bool refPoint1IsCentroid =
false;
634 bool refPoint2IsCentroid =
false;
639 if ( props.contains( QStringLiteral(
"type" ) ) )
641 if ( props.contains( QStringLiteral(
"coordinate_mode" ) ) )
643 if ( props.contains( QStringLiteral(
"spread" ) ) )
645 if ( props.contains( QStringLiteral(
"color_type" ) ) )
647 if ( props.contains( QStringLiteral(
"gradient_color" ) ) )
652 else if ( props.contains( QStringLiteral(
"color" ) ) )
656 if ( props.contains( QStringLiteral(
"gradient_color2" ) ) )
661 if ( props.contains( QStringLiteral(
"reference_point1" ) ) )
663 if ( props.contains( QStringLiteral(
"reference_point1_iscentroid" ) ) )
664 refPoint1IsCentroid = props[QStringLiteral(
"reference_point1_iscentroid" )].toInt();
665 if ( props.contains( QStringLiteral(
"reference_point2" ) ) )
667 if ( props.contains( QStringLiteral(
"reference_point2_iscentroid" ) ) )
668 refPoint2IsCentroid = props[QStringLiteral(
"reference_point2_iscentroid" )].toInt();
669 if ( props.contains( QStringLiteral(
"angle" ) ) )
670 angle = props[QStringLiteral(
"angle" )].toDouble();
672 if ( props.contains( QStringLiteral(
"offset" ) ) )
689 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
691 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
694 sl->setReferencePoint1IsCentroid( refPoint1IsCentroid );
696 sl->setReferencePoint2IsCentroid( refPoint2IsCentroid );
697 sl->setAngle(
angle );
699 sl->setColorRamp( gradientRamp );
701 sl->restoreOldDataDefinedProperties( props );
718 return QStringLiteral(
"GradientFill" );
721void QgsGradientFillSymbolLayer::applyDataDefinedSymbology(
QgsSymbolRenderContext &context,
const QPolygonF &points )
766 if ( currentType == QObject::tr(
"linear" ) )
770 else if ( currentType == QObject::tr(
"radial" ) )
774 else if ( currentType == QObject::tr(
"conical" ) )
788 if ( currentCoordMode == QObject::tr(
"feature" ) )
792 else if ( currentCoordMode == QObject::tr(
"viewport" ) )
806 if ( currentSpread == QObject::tr(
"pad" ) )
810 else if ( currentSpread == QObject::tr(
"repeat" ) )
814 else if ( currentSpread == QObject::tr(
"reflect" ) )
861 if ( refPoint1IsCentroid || refPoint2IsCentroid )
866 QRectF bbox = points.boundingRect();
867 double centroidX = ( centroid.x() - bbox.left() ) / bbox.width();
868 double centroidY = ( centroid.y() - bbox.top() ) / bbox.height();
870 if ( refPoint1IsCentroid )
872 refPoint1X = centroidX;
873 refPoint1Y = centroidY;
875 if ( refPoint2IsCentroid )
877 refPoint2X = centroidX;
878 refPoint2Y = centroidY;
884 spread, QPointF( refPoint1X, refPoint1Y ), QPointF( refPoint2X, refPoint2Y ),
angle );
887QPointF QgsGradientFillSymbolLayer::rotateReferencePoint( QPointF refPoint,
double angle )
892 QLineF refLine = QLineF( QPointF( 0.5, 0.5 ), refPoint );
894 refLine.setAngle( refLine.angle() +
angle );
896 QPointF rotatedReferencePoint = refLine.p2();
898 if ( rotatedReferencePoint.x() > 1 )
899 rotatedReferencePoint.setX( 1 );
900 if ( rotatedReferencePoint.x() < 0 )
901 rotatedReferencePoint.setX( 0 );
902 if ( rotatedReferencePoint.y() > 1 )
903 rotatedReferencePoint.setY( 1 );
904 if ( rotatedReferencePoint.y() < 0 )
905 rotatedReferencePoint.setY( 0 );
907 return rotatedReferencePoint;
914 QPointF referencePoint1, QPointF referencePoint2,
const double angle )
919 QColor fillColor2 =
color2;
920 fillColor2.setAlphaF( context.
opacity() * fillColor2.alphaF() );
931 gradient = QLinearGradient( rotatedReferencePoint1, rotatedReferencePoint2 );
934 gradient = QRadialGradient( rotatedReferencePoint1, QLineF( rotatedReferencePoint1, rotatedReferencePoint2 ).length() );
937 gradient = QConicalGradient( rotatedReferencePoint1, QLineF( rotatedReferencePoint1, rotatedReferencePoint2 ).
angle() );
943 gradient.setCoordinateMode( QGradient::ObjectBoundingMode );
946 gradient.setCoordinateMode( QGradient::StretchToDeviceMode );
952 gradient.setSpread( QGradient::PadSpread );
955 gradient.setSpread( QGradient::ReflectSpread );
958 gradient.setSpread( QGradient::RepeatSpread );
967 QgsGradientColorRamp *gradRamp =
static_cast<QgsGradientColorRamp *
>( gradientRamp );
974 gradient.setColorAt( 1.0, fillColor2 );
978 brush = QBrush( gradient );
985 selColor.setAlphaF( context.
opacity() );
1002 applyDataDefinedSymbology( context, points );
1006 p->setPen( Qt::NoPen );
1039 map[QStringLiteral(
"color_type" )] = QString::number(
static_cast< int >(
mGradientColorType ) );
1040 map[QStringLiteral(
"type" )] = QString::number(
static_cast<int>(
mGradientType ) );
1041 map[QStringLiteral(
"coordinate_mode" )] = QString::number(
static_cast< int >(
mCoordinateMode ) );
1042 map[QStringLiteral(
"spread" )] = QString::number(
static_cast< int >(
mGradientSpread ) );
1047 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
1073 return sl.release();
1138 if ( props.contains( QStringLiteral(
"color_type" ) ) )
1142 if ( props.contains( QStringLiteral(
"shapeburst_color" ) ) )
1147 else if ( props.contains( QStringLiteral(
"color" ) ) )
1152 if ( props.contains( QStringLiteral(
"shapeburst_color2" ) ) )
1157 else if ( props.contains( QStringLiteral(
"gradient_color2" ) ) )
1161 if ( props.contains( QStringLiteral(
"blur_radius" ) ) )
1163 blurRadius = props[QStringLiteral(
"blur_radius" )].toInt();
1165 if ( props.contains( QStringLiteral(
"use_whole_shape" ) ) )
1167 useWholeShape = props[QStringLiteral(
"use_whole_shape" )].toInt();
1169 if ( props.contains( QStringLiteral(
"max_distance" ) ) )
1171 maxDistance = props[QStringLiteral(
"max_distance" )].toDouble();
1173 if ( props.contains( QStringLiteral(
"offset" ) ) )
1192 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
1196 if ( props.contains( QStringLiteral(
"distance_unit" ) ) )
1200 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
1204 if ( props.contains( QStringLiteral(
"distance_map_unit_scale" ) ) )
1208 if ( props.contains( QStringLiteral(
"ignore_rings" ) ) )
1210 sl->setIgnoreRings( props[QStringLiteral(
"ignore_rings" )].toInt() );
1214 sl->setColorRamp( gradientRamp );
1217 sl->restoreOldDataDefinedProperties( props );
1219 return sl.release();
1224 return QStringLiteral(
"ShapeburstFill" );
1234 if ( mGradientRamp.get() == ramp )
1237 mGradientRamp.reset( ramp );
1240void QgsShapeburstFillSymbolLayer::applyDataDefinedSymbology(
QgsSymbolRenderContext &context, QColor &color, QColor &color2,
int &blurRadius,
bool &useWholeShape,
1241 double &maxDistance,
bool &ignoreRings )
1298 selColor.setAlphaF( context.
opacity() );
1299 mSelBrush = QBrush( selColor );
1316 if ( useSelectedColor )
1319 p->setBrush( mSelBrush );
1320 QPointF
offset = mOffset;
1355 int outputPixelMaxDist = 0;
1363 std::unique_ptr< QgsGradientColorRamp > twoColorGradientRamp;
1366 twoColorGradientRamp = std::make_unique< QgsGradientColorRamp >( color1,
color2 );
1370 p->setPen( QPen( Qt::NoPen ) );
1375 int pointsWidth =
static_cast< int >( std::round( points.boundingRect().width() ) );
1376 int pointsHeight =
static_cast< int >( std::round( points.boundingRect().height() ) );
1377 int imWidth = pointsWidth + ( sideBuffer * 2 );
1378 int imHeight = pointsHeight + ( sideBuffer * 2 );
1384 auto fillImage = std::make_unique< QImage >( imWidth,
1385 imHeight, QImage::Format_ARGB32_Premultiplied );
1386 if ( fillImage->isNull() )
1396 auto alphaImage = std::make_unique< QImage >( fillImage->width(), fillImage->height(), QImage::Format_ARGB32_Premultiplied );
1397 if ( alphaImage->isNull() )
1409 fillImage->fill( Qt::black );
1415 alphaImage->fill( Qt::transparent );
1421 QPainter imgPainter;
1422 imgPainter.begin( alphaImage.get() );
1423 imgPainter.setRenderHint( QPainter::Antialiasing,
true );
1424 imgPainter.setBrush( QBrush( Qt::white ) );
1425 imgPainter.setPen( QPen( Qt::black ) );
1426 imgPainter.translate( -points.boundingRect().left() + sideBuffer, - points.boundingRect().top() + sideBuffer );
1435 imgPainter.begin( fillImage.get() );
1438 imgPainter.drawImage( 0, 0, *alphaImage );
1445 imgPainter.setBrush( QBrush( Qt::white ) );
1446 imgPainter.setPen( QPen( Qt::black ) );
1447 imgPainter.translate( -points.boundingRect().left() + sideBuffer, - points.boundingRect().top() + sideBuffer );
1456 double *dtArray = distanceTransform( fillImage.get(), context.
renderContext() );
1476 imgPainter.begin( fillImage.get() );
1477 imgPainter.setCompositionMode( QPainter::CompositionMode_DestinationIn );
1478 imgPainter.drawImage( 0, 0, *alphaImage );
1486 QPointF
offset = mOffset;
1503 p->drawImage( points.boundingRect().left() - sideBuffer, points.boundingRect().top() - sideBuffer, *fillImage );
1514void QgsShapeburstFillSymbolLayer::distanceTransform1d(
double *f,
int n,
int *v,
double *z,
double *d )
1520 for (
int q = 1; q <= n - 1; q++ )
1522 double s = ( ( f[q] +
static_cast< double >( q ) * q ) - ( f[v[k]] + (
static_cast< double >( v[k] ) * v[k] ) ) ) / ( 2 * q - 2 * v[k] );
1526 s = ( ( f[q] +
static_cast< double >( q ) * q ) - ( f[v[k]] + (
static_cast< double >( v[k] ) * v[k] ) ) ) / ( 2 * q - 2 * v[k] );
1535 for (
int q = 0; q <= n - 1; q++ )
1537 while ( z[k + 1] < q )
1539 d[q] =
static_cast< double >( q - v[k] ) * ( q - v[k] ) + f[v[k]];
1544void QgsShapeburstFillSymbolLayer::distanceTransform2d(
double *im,
int width,
int height,
QgsRenderContext &context )
1546 int maxDimension = std::max( width, height );
1547 double *f =
new double[ maxDimension ];
1548 int *v =
new int[ maxDimension ];
1549 double *z =
new double[ maxDimension + 1 ];
1550 double *d =
new double[ maxDimension ];
1553 for (
int x = 0; x < width; x++ )
1558 for (
int y = 0; y < height; y++ )
1560 f[y] = im[ x +
static_cast< std::size_t
>( y ) * width ];
1562 distanceTransform1d( f, height, v, z, d );
1563 for (
int y = 0; y < height; y++ )
1565 im[ x +
static_cast< std::size_t
>( y ) * width ] = d[y];
1570 for (
int y = 0; y < height; y++ )
1575 for (
int x = 0; x < width; x++ )
1577 f[x] = im[ x +
static_cast< std::size_t
>( y ) * width ];
1579 distanceTransform1d( f, width, v, z, d );
1580 for (
int x = 0; x < width; x++ )
1582 im[ x +
static_cast< std::size_t
>( y ) * width ] = d[x];
1593double *QgsShapeburstFillSymbolLayer::distanceTransform( QImage *im,
QgsRenderContext &context )
1595 int width = im->width();
1596 int height = im->height();
1598 double *dtArray =
new double[
static_cast< std::size_t
>( width ) * height];
1602 std::size_t idx = 0;
1603 for (
int heightIndex = 0; heightIndex < height; ++heightIndex )
1608 const QRgb *scanLine =
reinterpret_cast< const QRgb *
>( im->constScanLine( heightIndex ) );
1609 for (
int widthIndex = 0; widthIndex < width; ++widthIndex )
1611 tmpRgb = scanLine[widthIndex];
1612 if ( qRed( tmpRgb ) == 0 )
1620 dtArray[ idx ] =
INF;
1627 distanceTransform2d( dtArray, width, height, context );
1632void QgsShapeburstFillSymbolLayer::dtArrayToQImage(
double *array, QImage *im,
QgsColorRamp *ramp,
QgsRenderContext &context,
bool useWholeShape,
int maxPixelDistance )
1634 int width = im->width();
1635 int height = im->height();
1638 double maxDistanceValue;
1643 double dtMaxValue = array[0];
1644 for ( std::size_t i = 1; i < static_cast< std::size_t >( width ) * height; ++i )
1646 if ( array[i] > dtMaxValue )
1648 dtMaxValue = array[i];
1653 maxDistanceValue = std::sqrt( dtMaxValue );
1658 maxDistanceValue = maxPixelDistance;
1662 std::size_t idx = 0;
1663 double squaredVal = 0;
1666 for (
int heightIndex = 0; heightIndex < height; ++heightIndex )
1671 QRgb *scanLine =
reinterpret_cast< QRgb *
>( im->scanLine( heightIndex ) );
1672 for (
int widthIndex = 0; widthIndex < width; ++widthIndex )
1675 squaredVal = array[idx];
1678 if ( maxDistanceValue > 0 )
1680 pixVal = squaredVal > 0 ? std::min( ( std::sqrt( squaredVal ) / maxDistanceValue ), 1.0 ) : 0;
1689 scanLine[widthIndex] = qPremultiply( ramp->
color( pixVal ).rgba() );
1700 map[QStringLiteral(
"color_type" )] = QString::number(
static_cast< int >( mColorType ) );
1701 map[QStringLiteral(
"blur_radius" )] = QString::number( mBlurRadius );
1702 map[QStringLiteral(
"use_whole_shape" )] = QString::number( mUseWholeShape );
1703 map[QStringLiteral(
"max_distance" )] = QString::number( mMaxDistance );
1706 map[QStringLiteral(
"ignore_rings" )] = QString::number( mIgnoreRings );
1710 if ( mGradientRamp )
1712 map.insert( mGradientRamp->properties() );
1720 auto sl = std::make_unique< QgsShapeburstFillSymbolLayer >(
mColor, mColor2, mColorType, mBlurRadius, mUseWholeShape, mMaxDistance );
1721 if ( mGradientRamp )
1723 sl->setColorRamp( mGradientRamp->clone() );
1725 sl->setDistanceUnit( mDistanceUnit );
1726 sl->setDistanceMapUnitScale( mDistanceMapUnitScale );
1727 sl->setIgnoreRings( mIgnoreRings );
1728 sl->setOffset( mOffset );
1729 sl->setOffsetUnit( mOffsetUnit );
1730 sl->setOffsetMapUnitScale( mOffsetMapUnitScale );
1733 return sl.release();
1738 double offsetBleed = context.
convertToPainterUnits( std::max( std::fabs( mOffset.x() ), std::fabs( mOffset.y() ) ), mOffsetUnit, mOffsetMapUnitScale );
1749 mDistanceUnit = unit;
1755 if ( mDistanceUnit == mOffsetUnit )
1757 return mDistanceUnit;
1770 mDistanceMapUnitScale = scale;
1771 mOffsetMapUnitScale = scale;
1776 if ( mDistanceMapUnitScale == mOffsetMapUnitScale )
1778 return mDistanceMapUnitScale;
1803 p->setPen( QPen( Qt::NoPen ) );
1805 QTransform bkTransform =
mBrush.transform();
1809 QTransform t =
mBrush.transform();
1810 t.translate( leftCorner.x(), leftCorner.y() );
1811 mBrush.setTransform( t );
1815 QTransform t =
mBrush.transform();
1816 t.translate( 0, 0 );
1817 mBrush.setTransform( t );
1821 if ( useSelectedColor )
1824 p->setBrush( QBrush( selColor ) );
1830 QTransform t =
mBrush.transform();
1832 mBrush.setTransform( t );
1837 mBrush.setTransform( bkTransform );
1873 return Qt::SolidLine;
1877 return Qt::SolidLine;
1881 return mStroke->dxfPenStyle();
1917 , mPatternWidth( width )
1921 mColor = QColor( 255, 255, 255 );
1927 , mPatternWidth( width )
1928 , mSvgData( svgData )
1933 mColor = QColor( 255, 255, 255 );
1934 setDefaultSvgParams();
1942 mPatternWidthUnit = unit;
1943 mSvgStrokeWidthUnit = unit;
1946 mStroke->setOutputUnit( unit );
1952 if ( mPatternWidthUnit != unit || mSvgStrokeWidthUnit != unit ||
mStrokeWidthUnit != unit )
1962 mPatternWidthMapUnitScale = scale;
1963 mSvgStrokeWidthMapUnitScale = scale;
1969 mPatternWidthMapUnitScale == mSvgStrokeWidthMapUnitScale &&
1972 return mPatternWidthMapUnitScale;
1982 mSvgFilePath = svgPath;
1983 setDefaultSvgParams();
1993 if (
properties.contains( QStringLiteral(
"width" ) ) )
1995 width =
properties[QStringLiteral(
"width" )].toDouble();
1997 if (
properties.contains( QStringLiteral(
"svgFile" ) ) )
2001 if (
properties.contains( QStringLiteral(
"angle" ) ) )
2006 std::unique_ptr< QgsSVGFillSymbolLayer > symbolLayer;
2009 symbolLayer = std::make_unique< QgsSVGFillSymbolLayer >(
svgFilePath, width,
angle );
2013 if (
properties.contains( QStringLiteral(
"data" ) ) )
2015 data = QByteArray::fromHex(
properties[QStringLiteral(
"data" )].toString().toLocal8Bit() );
2017 symbolLayer = std::make_unique< QgsSVGFillSymbolLayer >( data, width,
angle );
2021 if (
properties.contains( QStringLiteral(
"svgFillColor" ) ) )
2026 else if (
properties.contains( QStringLiteral(
"color" ) ) )
2030 if (
properties.contains( QStringLiteral(
"svgOutlineColor" ) ) )
2035 else if (
properties.contains( QStringLiteral(
"outline_color" ) ) )
2039 else if (
properties.contains( QStringLiteral(
"line_color" ) ) )
2043 if (
properties.contains( QStringLiteral(
"svgOutlineWidth" ) ) )
2046 symbolLayer->setSvgStrokeWidth(
properties[QStringLiteral(
"svgOutlineWidth" )].toDouble() );
2048 else if (
properties.contains( QStringLiteral(
"outline_width" ) ) )
2050 symbolLayer->setSvgStrokeWidth(
properties[QStringLiteral(
"outline_width" )].toDouble() );
2052 else if (
properties.contains( QStringLiteral(
"line_width" ) ) )
2054 symbolLayer->setSvgStrokeWidth(
properties[QStringLiteral(
"line_width" )].toDouble() );
2058 if (
properties.contains( QStringLiteral(
"pattern_width_unit" ) ) )
2062 if (
properties.contains( QStringLiteral(
"pattern_width_map_unit_scale" ) ) )
2066 if (
properties.contains( QStringLiteral(
"svg_outline_width_unit" ) ) )
2070 if (
properties.contains( QStringLiteral(
"svg_outline_width_map_unit_scale" ) ) )
2074 if (
properties.contains( QStringLiteral(
"outline_width_unit" ) ) )
2078 if (
properties.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
2083 if (
properties.contains( QStringLiteral(
"parameters" ) ) )
2089 symbolLayer->restoreOldDataDefinedProperties(
properties );
2091 return symbolLayer.release();
2096 QVariantMap::iterator it =
properties.find( QStringLiteral(
"svgFile" ) );
2108 return QStringLiteral(
"SVGFill" );
2111void QgsSVGFillSymbolLayer::applyPattern( QBrush &brush,
const QString &svgFilePath,
double patternWidth,
Qgis::RenderUnit patternWidthUnit,
2112 const QColor &svgFillColor,
const QColor &svgStrokeColor,
double svgStrokeWidth,
2116 if ( mSvgViewBox.isNull() )
2123 if (
static_cast< int >( size ) < 1.0 || 10000.0 < size )
2125 brush.setTextureImage( QImage() );
2129 bool fitsInCache =
true;
2137 double hwRatio = 1.0;
2138 if ( patternPict.width() > 0 )
2140 hwRatio =
static_cast< double >( patternPict.height() ) /
static_cast< double >( patternPict.width() );
2142 patternImage = QImage(
static_cast< int >( size ),
static_cast< int >( size * hwRatio ), QImage::Format_ARGB32_Premultiplied );
2143 patternImage.fill( 0 );
2145 QPainter p( &patternImage );
2146 p.drawPicture( QPointF( size / 2, size * hwRatio / 2 ), patternPict );
2149 QTransform brushTransform;
2152 QImage transparentImage = patternImage.copy();
2154 brush.setTextureImage( transparentImage );
2158 brush.setTextureImage( patternImage );
2160 brush.setTransform( brushTransform );
2168 applyPattern(
mBrush, mSvgFilePath, mPatternWidth, mPatternWidthUnit,
mColor, mSvgStrokeColor, mSvgStrokeWidth, mSvgStrokeWidthUnit, context, mPatternWidthMapUnitScale, mSvgStrokeWidthMapUnitScale, evaluatedParameters );
2192 mStroke->renderPolyline( points, context.
feature(), context.
renderContext(), -1, useSelectedColor );
2195 for (
auto ringIt = rings->constBegin(); ringIt != rings->constEnd(); ++ringIt )
2197 mStroke->renderPolyline( *ringIt, context.
feature(), context.
renderContext(), -1, useSelectedColor );
2206 if ( !mSvgFilePath.isEmpty() )
2208 map.insert( QStringLiteral(
"svgFile" ), mSvgFilePath );
2212 map.insert( QStringLiteral(
"data" ), QString( mSvgData.toHex() ) );
2215 map.insert( QStringLiteral(
"width" ), QString::number( mPatternWidth ) );
2216 map.insert( QStringLiteral(
"angle" ), QString::number(
mAngle ) );
2221 map.insert( QStringLiteral(
"outline_width" ), QString::number( mSvgStrokeWidth ) );
2238 std::unique_ptr< QgsSVGFillSymbolLayer > clonedLayer;
2239 if ( !mSvgFilePath.isEmpty() )
2241 clonedLayer = std::make_unique< QgsSVGFillSymbolLayer >( mSvgFilePath, mPatternWidth,
mAngle );
2242 clonedLayer->setSvgFillColor(
mColor );
2243 clonedLayer->setSvgStrokeColor( mSvgStrokeColor );
2244 clonedLayer->setSvgStrokeWidth( mSvgStrokeWidth );
2248 clonedLayer = std::make_unique< QgsSVGFillSymbolLayer >( mSvgData, mPatternWidth,
mAngle );
2251 clonedLayer->setPatternWidthUnit( mPatternWidthUnit );
2252 clonedLayer->setPatternWidthMapUnitScale( mPatternWidthMapUnitScale );
2253 clonedLayer->setSvgStrokeWidthUnit( mSvgStrokeWidthUnit );
2254 clonedLayer->setSvgStrokeWidthMapUnitScale( mSvgStrokeWidthMapUnitScale );
2258 clonedLayer->setParameters( mParameters );
2262 clonedLayer->setSubSymbol( mStroke->clone() );
2266 return clonedLayer.release();
2273 toSld( doc, element, context );
2279 QDomElement symbolizerElem = doc.createElement( QStringLiteral(
"se:PolygonSymbolizer" ) );
2280 if ( !props.value( QStringLiteral(
"uom" ), QString() ).toString().isEmpty() )
2281 symbolizerElem.setAttribute( QStringLiteral(
"uom" ), props.value( QStringLiteral(
"uom" ), QString() ).toString() );
2282 element.appendChild( symbolizerElem );
2286 QDomElement fillElem = doc.createElement( QStringLiteral(
"se:Fill" ) );
2287 symbolizerElem.appendChild( fillElem );
2289 QDomElement graphicFillElem = doc.createElement( QStringLiteral(
"se:GraphicFill" ) );
2290 fillElem.appendChild( graphicFillElem );
2292 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
2293 graphicFillElem.appendChild( graphicElem );
2295 if ( !mSvgFilePath.isEmpty() )
2307 context.
pushWarning( QObject::tr(
"Exporting embedded SVG content to SLD is not supported" ) );
2313 double angle = props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toDouble( &ok );
2316 angleFunc = QStringLiteral(
"%1 + %2" ).arg( props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toString() ).arg(
mAngle );
2329 mStroke->toSld( doc, element, context );
2342 return mStroke.get();
2349 mStroke.reset(
nullptr );
2362 mStroke.reset( lineSymbol );
2372 if ( mStroke && mStroke->symbolLayer( 0 ) )
2374 double subLayerBleed = mStroke->symbolLayer( 0 )->estimateMaxBleed( context );
2375 return subLayerBleed;
2385 return QColor( Qt::black );
2387 return mStroke->
color();
2394 attr.unite( mStroke->usedAttributes( context ) );
2402 if ( mStroke && mStroke->hasDataDefinedProperties() )
2409 QString path, mimeType;
2411 Qt::PenStyle penStyle;
2412 double size, strokeWidth;
2414 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
2415 if ( fillElem.isNull() )
2418 QDomElement graphicFillElem = fillElem.firstChildElement( QStringLiteral(
"GraphicFill" ) );
2419 if ( graphicFillElem.isNull() )
2422 QDomElement graphicElem = graphicFillElem.firstChildElement( QStringLiteral(
"Graphic" ) );
2423 if ( graphicElem.isNull() )
2429 if ( mimeType != QLatin1String(
"image/svg+xml" ) )
2434 double scaleFactor = 1.0;
2435 const QString uom = element.attribute( QStringLiteral(
"uom" ) );
2437 size = size * scaleFactor;
2438 strokeWidth = strokeWidth * scaleFactor;
2445 double d = angleFunc.toDouble( &ok );
2450 auto sl = std::make_unique< QgsSVGFillSymbolLayer >( path, size,
angle );
2451 sl->setOutputUnit( sldUnitSize );
2454 sl->setSvgStrokeWidth( strokeWidth );
2457 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
2458 if ( !strokeElem.isNull() )
2464 layers.append( l.release() );
2469 return sl.release();
2487 double width = mPatternWidth;
2493 QString svgFile = mSvgFilePath;
2512 double strokeWidth = mSvgStrokeWidth;
2521 mSvgStrokeWidthUnit, context, mPatternWidthMapUnitScale, mSvgStrokeWidthMapUnitScale, evaluatedParameters );
2525void QgsSVGFillSymbolLayer::storeViewBox()
2527 if ( !mSvgData.isEmpty() )
2529 QSvgRenderer r( mSvgData );
2532 mSvgViewBox = r.viewBoxF();
2537 mSvgViewBox = QRectF();
2540void QgsSVGFillSymbolLayer::setDefaultSvgParams()
2542 if ( mSvgFilePath.isEmpty() )
2547 bool hasFillParam, hasFillOpacityParam, hasStrokeParam, hasStrokeWidthParam, hasStrokeOpacityParam;
2548 bool hasDefaultFillColor, hasDefaultFillOpacity, hasDefaultStrokeColor, hasDefaultStrokeWidth, hasDefaultStrokeOpacity;
2549 QColor defaultFillColor, defaultStrokeColor;
2550 double defaultStrokeWidth, defaultFillOpacity, defaultStrokeOpacity;
2552 hasFillOpacityParam, hasDefaultFillOpacity, defaultFillOpacity,
2553 hasStrokeParam, hasDefaultStrokeColor, defaultStrokeColor,
2554 hasStrokeWidthParam, hasDefaultStrokeWidth, defaultStrokeWidth,
2555 hasStrokeOpacityParam, hasDefaultStrokeOpacity, defaultStrokeOpacity );
2557 double newFillOpacity = hasFillOpacityParam ?
mColor.alphaF() : 1.0;
2558 double newStrokeOpacity = hasStrokeOpacityParam ? mSvgStrokeColor.alphaF() : 1.0;
2560 if ( hasDefaultFillColor )
2562 mColor = defaultFillColor;
2563 mColor.setAlphaF( newFillOpacity );
2565 if ( hasDefaultFillOpacity )
2567 mColor.setAlphaF( defaultFillOpacity );
2569 if ( hasDefaultStrokeColor )
2571 mSvgStrokeColor = defaultStrokeColor;
2572 mSvgStrokeColor.setAlphaF( newStrokeOpacity );
2574 if ( hasDefaultStrokeOpacity )
2576 mSvgStrokeColor.setAlphaF( defaultStrokeOpacity );
2578 if ( hasDefaultStrokeWidth )
2580 mSvgStrokeWidth = defaultStrokeWidth;
2593 mFillLineSymbol = std::make_unique<QgsLineSymbol>( );
2601 mFillLineSymbol->setWidth( w );
2607 mFillLineSymbol->setColor(
c );
2613 return mFillLineSymbol ? mFillLineSymbol->color() :
mColor;
2625 mFillLineSymbol.reset( qgis::down_cast<QgsLineSymbol *>( symbol ) );
2634 return mFillLineSymbol.get();
2640 if ( mFillLineSymbol )
2641 attr.unite( mFillLineSymbol->usedAttributes( context ) );
2649 if ( mFillLineSymbol && mFillLineSymbol->hasDataDefinedProperties() )
2671 double lineAngleRad { qDegreesToRadians( mLineAngle ) };
2673 const int quadrant {
static_cast<int>( lineAngleRad / M_PI_2 ) };
2674 Q_ASSERT( quadrant >= 0 && quadrant <= 3 );
2684 lineAngleRad -= M_PI / 2;
2689 lineAngleRad -= M_PI;
2694 lineAngleRad -= M_PI + M_PI_2;
2702 QSize size {
static_cast<int>( distancePx ),
static_cast<int>( distancePx ) };
2704 if (
static_cast<int>( mLineAngle ) % 90 != 0 )
2706 size = QSize(
static_cast<int>( distancePx / std::sin( lineAngleRad ) ),
static_cast<int>( distancePx / std::cos( lineAngleRad ) ) );
2709 QPixmap pixmap( size );
2710 pixmap.fill( Qt::transparent );
2712 painter.begin( &pixmap );
2713 painter.setRenderHint( QPainter::Antialiasing );
2721 std::unique_ptr< QgsLinePatternFillSymbolLayer > layerClone(
clone() );
2722 layerClone->setOffset( 0 );
2723 layerClone->drawPreviewIcon( symbolContext, pixmap.size() );
2725 return pixmap.toImage();
2736 mDistanceUnit = unit;
2737 mLineWidthUnit = unit;
2740 if ( mFillLineSymbol )
2741 mFillLineSymbol->setOutputUnit( unit );
2764 mDistanceMapUnitScale = scale;
2765 mLineWidthMapUnitScale = scale;
2766 mOffsetMapUnitScale = scale;
2772 mDistanceMapUnitScale == mLineWidthMapUnitScale &&
2773 mLineWidthMapUnitScale == mOffsetMapUnitScale )
2775 return mDistanceMapUnitScale;
2782 auto patternLayer = std::make_unique< QgsLinePatternFillSymbolLayer >();
2788 QColor
color( Qt::black );
2791 if (
properties.contains( QStringLiteral(
"lineangle" ) ) )
2796 else if (
properties.contains( QStringLiteral(
"angle" ) ) )
2800 patternLayer->setLineAngle(
lineAngle );
2802 if (
properties.contains( QStringLiteral(
"distance" ) ) )
2806 patternLayer->setDistance(
distance );
2808 if (
properties.contains( QStringLiteral(
"linewidth" ) ) )
2813 else if (
properties.contains( QStringLiteral(
"outline_width" ) ) )
2817 else if (
properties.contains( QStringLiteral(
"line_width" ) ) )
2821 patternLayer->setLineWidth(
lineWidth );
2823 if (
properties.contains( QStringLiteral(
"color" ) ) )
2827 else if (
properties.contains( QStringLiteral(
"outline_color" ) ) )
2831 else if (
properties.contains( QStringLiteral(
"line_color" ) ) )
2835 patternLayer->setColor(
color );
2837 if (
properties.contains( QStringLiteral(
"offset" ) ) )
2841 patternLayer->setOffset(
offset );
2844 if (
properties.contains( QStringLiteral(
"distance_unit" ) ) )
2848 if (
properties.contains( QStringLiteral(
"distance_map_unit_scale" ) ) )
2852 if (
properties.contains( QStringLiteral(
"line_width_unit" ) ) )
2856 else if (
properties.contains( QStringLiteral(
"outline_width_unit" ) ) )
2860 if (
properties.contains( QStringLiteral(
"line_width_map_unit_scale" ) ) )
2864 if (
properties.contains( QStringLiteral(
"offset_unit" ) ) )
2868 if (
properties.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
2872 if (
properties.contains( QStringLiteral(
"outline_width_unit" ) ) )
2876 if (
properties.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
2880 if (
properties.contains( QStringLiteral(
"coordinate_reference" ) ) )
2884 if (
properties.contains( QStringLiteral(
"clip_mode" ) ) )
2889 patternLayer->restoreOldDataDefinedProperties(
properties );
2891 return patternLayer.release();
2896 return QStringLiteral(
"LinePatternFill" );
2899bool QgsLinePatternFillSymbolLayer::applyPattern(
const QgsSymbolRenderContext &context, QBrush &brush,
double lineAngle,
double distance )
2901 mBrush.setTextureImage( QImage() );
2903 if ( !mFillLineSymbol )
2908 std::unique_ptr< QgsLineSymbol > fillLineSymbol( mFillLineSymbol->clone() );
2909 if ( !fillLineSymbol )
2925 outputPixelOffset = std::fmod( outputPixelOffset, outputPixelDist );
2926 if ( outputPixelOffset > outputPixelDist / 2.0 )
2927 outputPixelOffset -= outputPixelDist;
2931 double outputPixelBleed = 0;
2932 double outputPixelInterval = 0;
2933 for (
int i = 0; i < fillLineSymbol->symbolLayerCount(); i++ )
2937 outputPixelBleed = std::max( outputPixelBleed, outputPixelLayerBleed );
2939 QgsMarkerLineSymbolLayer *markerLineLayer =
dynamic_cast<QgsMarkerLineSymbolLayer *
>( layer );
2940 if ( markerLineLayer )
2949 outputPixelInterval = std::max( outputPixelInterval, outputPixelLayerInterval );
2953 if ( outputPixelInterval > 0 )
2957 double intervalScale = std::round( outputPixelInterval ) / outputPixelInterval;
2958 outputPixelInterval = std::round( outputPixelInterval );
2960 for (
int i = 0; i < fillLineSymbol->symbolLayerCount(); i++ )
2964 QgsMarkerLineSymbolLayer *markerLineLayer =
dynamic_cast<QgsMarkerLineSymbolLayer *
>( layer );
2965 if ( markerLineLayer )
2979 height = outputPixelDist;
2980 width = outputPixelInterval > 0 ? outputPixelInterval : height;
2984 width = outputPixelDist;
2985 height = outputPixelInterval > 0 ? outputPixelInterval : width;
2989 height = outputPixelDist / std::cos(
lineAngle * M_PI / 180 );
2990 width = outputPixelDist / std::sin(
lineAngle * M_PI / 180 );
2993 lineAngle = 180 * std::atan2(
static_cast< double >( height ),
static_cast< double >( width ) ) / M_PI;
2999 height = std::abs( height );
3000 width = std::abs( width );
3002 outputPixelDist = std::abs( height * std::cos(
lineAngle * M_PI / 180 ) );
3006 int offsetHeight =
static_cast< int >( std::round( outputPixelOffset / std::cos(
lineAngle * M_PI / 180 ) ) );
3007 outputPixelOffset = offsetHeight * std::cos(
lineAngle * M_PI / 180 );
3016 int bufferMulti =
static_cast< int >( std::max( std::ceil( outputPixelBleed / width ), std::ceil( outputPixelBleed / width ) ) );
3020 bufferMulti = std::max( bufferMulti, 1 );
3022 int xBuffer = width * bufferMulti;
3023 int yBuffer = height * bufferMulti;
3024 int innerWidth = width;
3025 int innerHeight = height;
3026 width += 2 * xBuffer;
3027 height += 2 * yBuffer;
3030 if ( width > 2000 || height > 2000 || width == 0 || height == 0 )
3035 QImage patternImage( width, height, QImage::Format_ARGB32 );
3036 patternImage.fill( 0 );
3038 QPointF p1, p2, p3, p4, p5, p6;
3041 p1 = QPointF( 0, yBuffer );
3042 p2 = QPointF( width, yBuffer );
3043 p3 = QPointF( 0, yBuffer + innerHeight );
3044 p4 = QPointF( width, yBuffer + innerHeight );
3048 p1 = QPointF( xBuffer, height );
3049 p2 = QPointF( xBuffer, 0 );
3050 p3 = QPointF( xBuffer + innerWidth, height );
3051 p4 = QPointF( xBuffer + innerWidth, 0 );
3055 dx = outputPixelDist * std::cos( ( 90 -
lineAngle ) * M_PI / 180.0 );
3056 dy = outputPixelDist * std::sin( ( 90 -
lineAngle ) * M_PI / 180.0 );
3057 p1 = QPointF( 0, height );
3058 p2 = QPointF( width, 0 );
3059 p3 = QPointF( -dx, height - dy );
3060 p4 = QPointF( width - dx, -dy );
3061 p5 = QPointF( dx, height + dy );
3062 p6 = QPointF( width + dx, dy );
3066 dx = outputPixelDist * std::cos( ( 90 -
lineAngle ) * M_PI / 180.0 );
3067 dy = outputPixelDist * std::sin( ( 90 -
lineAngle ) * M_PI / 180.0 );
3068 p1 = QPointF( width, 0 );
3069 p2 = QPointF( 0, height );
3070 p3 = QPointF( width - dx, -dy );
3071 p4 = QPointF( -dx, height - dy );
3072 p5 = QPointF( width + dx, dy );
3073 p6 = QPointF( dx, height + dy );
3077 dy = outputPixelDist * std::cos( ( 180 -
lineAngle ) * M_PI / 180 );
3078 dx = outputPixelDist * std::sin( ( 180 -
lineAngle ) * M_PI / 180 );
3079 p1 = QPointF( 0, 0 );
3080 p2 = QPointF( width, height );
3081 p5 = QPointF( dx, -dy );
3082 p6 = QPointF( width + dx, height - dy );
3083 p3 = QPointF( -dx, dy );
3084 p4 = QPointF( width - dx, height + dy );
3088 dy = outputPixelDist * std::cos( ( 180 -
lineAngle ) * M_PI / 180 );
3089 dx = outputPixelDist * std::sin( ( 180 -
lineAngle ) * M_PI / 180 );
3090 p1 = QPointF( width, height );
3091 p2 = QPointF( 0, 0 );
3092 p5 = QPointF( width + dx, height - dy );
3093 p6 = QPointF( dx, -dy );
3094 p3 = QPointF( width - dx, height + dy );
3095 p4 = QPointF( -dx, dy );
3102 p3 = QPointF( tempPt.x(), tempPt.y() );
3104 p4 = QPointF( tempPt.x(), tempPt.y() );
3106 p5 = QPointF( tempPt.x(), tempPt.y() );
3108 p6 = QPointF( tempPt.x(), tempPt.y() );
3112 p1 = QPointF( tempPt.x(), tempPt.y() );
3114 p2 = QPointF( tempPt.x(), tempPt.y() );
3117 QPainter p( &patternImage );
3121 p.setRenderHint( QPainter::Antialiasing,
false );
3122 QPen pen( QColor( Qt::black ) );
3123 pen.setWidthF( 0.1 );
3124 pen.setCapStyle( Qt::FlatCap );
3129 QPolygon polygon = QPolygon() << QPoint( 0, 0 ) << QPoint( width - 1, 0 ) << QPoint( width - 1, height - 1 ) << QPoint( 0, height - 1 ) << QPoint( 0, 0 );
3130 p.drawPolygon( polygon );
3132 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 );
3133 p.drawPolygon( polygon );
3139 p.setRenderHint( QPainter::Antialiasing,
true );
3142 QgsRenderContext lineRenderContext;
3152 fillLineSymbol->startRender( lineRenderContext, context.
fields() );
3154 QVector<QPolygonF> polygons;
3155 polygons.append( QPolygonF() << p1 << p2 );
3156 polygons.append( QPolygonF() << p3 << p4 );
3159 polygons.append( QPolygonF() << p5 << p6 );
3163 for (
const QPolygonF &polygon : std::as_const( polygons ) )
3165 fillLineSymbol->renderPolyline( polygon, context.
feature(), lineRenderContext, -1, useSelectedColor );
3168 fillLineSymbol->stopRender( lineRenderContext );
3172 patternImage = patternImage.copy( xBuffer, yBuffer, patternImage.width() - 2 * xBuffer, patternImage.height() - 2 * yBuffer );
3177 QImage transparentImage = patternImage.copy();
3179 brush.setTextureImage( transparentImage );
3183 brush.setTextureImage( patternImage );
3186 QTransform brushTransform;
3187 brush.setTransform( brushTransform );
3197 || ( mFillLineSymbol && mFillLineSymbol->hasDataDefinedProperties() )
3201 if ( !mRenderUsingLines )
3205 mRenderUsingLines = !applyPattern( context,
mBrush, mLineAngle, mDistance );
3208 if ( mRenderUsingLines && mFillLineSymbol )
3212 mFillLineSymbolRenderStarted =
true;
3218 if ( mFillLineSymbolRenderStarted )
3221 mFillLineSymbolRenderStarted =
false;
3228 if ( !useSelectedColor && !mRenderUsingLines )
3235 if ( !mFillLineSymbol )
3238 if ( !mFillLineSymbolRenderStarted )
3242 mFillLineSymbolRenderStarted =
true;
3273 outputPixelOffset = std::fmod( outputPixelOffset, outputPixelDistance );
3274 if ( outputPixelOffset > outputPixelDistance / 2.0 )
3275 outputPixelOffset -= outputPixelDistance;
3277 p->setPen( QPen( Qt::NoPen ) );
3284 outputPixelDistance = std::max(
3288 outputPixelDistance );
3306 std::unique_ptr< QgsPolygon > shapePolygon;
3307 std::unique_ptr< QgsGeometryEngine > shapeEngine;
3315 shapePolygon = std::make_unique< QgsPolygon >();
3317 shapePolygon->setExteriorRing( fromPolygon.release() );
3320 for (
const QPolygonF &ring : *rings )
3323 shapePolygon->addInteriorRing( fromRing.release() );
3327 shapeEngine->prepareGeometry();
3334 path.addPolygon( points );
3337 for (
const QPolygonF &ring : *rings )
3339 path.addPolygon( ring );
3342 p->setClipPath( path, Qt::IntersectClip );
3348 const QRectF boundingRect = points.boundingRect();
3350 QTransform invertedRotateTransform;
3356 QTransform transform;
3357 if ( applyBrushTransform )
3360 transform.translate( -boundingRect.center().x(),
3361 -boundingRect.center().y() );
3363 transform.translate( boundingRect.center().x(),
3364 boundingRect.center().y() );
3372 const QRectF transformedBounds = transform.map( points ).boundingRect();
3376 left = transformedBounds.left() - buffer * 2;
3377 top = transformedBounds.top() - buffer * 2;
3378 right = transformedBounds.right() + buffer * 2;
3379 bottom = transformedBounds.bottom() + buffer * 2;
3380 invertedRotateTransform = transform.inverted();
3382 if ( !applyBrushTransform )
3384 top -= transformedBounds.top() - ( outputPixelDistance * std::floor( transformedBounds.top() / outputPixelDistance ) );
3389 const bool needsExpressionContext = mFillLineSymbol->hasDataDefinedProperties();
3394 int currentLine = 0;
3395 for (
double currentY = top; currentY <= bottom; currentY += outputPixelDistance )
3400 if ( needsExpressionContext )
3404 double y1 = currentY;
3406 double y2 = currentY;
3407 invertedRotateTransform.map( left, currentY - outputPixelOffset, &x1, &y1 );
3408 invertedRotateTransform.map( right, currentY - outputPixelOffset, &x2, &y2 );
3413 std::unique_ptr< QgsAbstractGeometry > intersection( shapeEngine->intersection( &ls ) );
3414 for (
auto it = intersection->const_parts_begin(); it != intersection->const_parts_end(); ++it )
3424 mFillLineSymbol->renderPolyline( QPolygonF() << QPointF( x1, y1 ) << QPointF( x2, y2 ), context.
feature(), context.
renderContext(), -1, useSelectedColor );
3436 map.insert( QStringLiteral(
"angle" ), QString::number( mLineAngle ) );
3437 map.insert( QStringLiteral(
"distance" ), QString::number( mDistance ) );
3438 map.insert( QStringLiteral(
"line_width" ), QString::number( mLineWidth ) );
3440 map.insert( QStringLiteral(
"offset" ), QString::number( mOffset ) );
3456 if ( mFillLineSymbol )
3469 toSld( doc, element, context );
3475 QDomElement symbolizerElem = doc.createElement( QStringLiteral(
"se:PolygonSymbolizer" ) );
3476 if ( !props.value( QStringLiteral(
"uom" ), QString() ).toString().isEmpty() )
3477 symbolizerElem.setAttribute( QStringLiteral(
"uom" ), props.value( QStringLiteral(
"uom" ), QString() ).toString() );
3478 element.appendChild( symbolizerElem );
3483 QDomElement fillElem = doc.createElement( QStringLiteral(
"se:Fill" ) );
3484 symbolizerElem.appendChild( fillElem );
3486 QDomElement graphicFillElem = doc.createElement( QStringLiteral(
"se:GraphicFill" ) );
3487 fillElem.appendChild( graphicFillElem );
3489 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
3490 graphicFillElem.appendChild( graphicElem );
3493 bool exportOk {
false };
3497 if ( ! image.isNull() )
3500 QString pngPath { info.completeSuffix().isEmpty() ? context.
exportFilePath() : context.
exportFilePath().chopped( info.completeSuffix().length() ).append( QStringLiteral(
"png" ) ) };
3501 pngPath = QgsFileUtils::uniquePath( pngPath );
3502 image.save( pngPath );
3511 QColor lineColor = mFillLineSymbol ? mFillLineSymbol->color() : QColor();
3512 double lineWidth = mFillLineSymbol ? mFillLineSymbol->width() : 0.0;
3520 double angle = props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toDouble( &ok );
3523 angleFunc = QStringLiteral(
"%1 + %2" ).arg( props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toString() ).arg( mLineAngle );
3527 angleFunc = QString::number(
angle + mLineAngle );
3532 QPointF lineOffset( std::sin( mLineAngle ) * mOffset, std::cos( mLineAngle ) * mOffset );
3541 QString featureStyle;
3542 featureStyle.append(
"Brush(" );
3543 featureStyle.append( QStringLiteral(
"fc:%1" ).arg(
mColor.name() ) );
3544 featureStyle.append( QStringLiteral(
",bc:%1" ).arg( QLatin1String(
"#00000000" ) ) );
3545 featureStyle.append(
",id:\"ogr-brush-2\"" );
3546 featureStyle.append( QStringLiteral(
",a:%1" ).arg( mLineAngle ) );
3547 featureStyle.append( QStringLiteral(
",s:%1" ).arg( mLineWidth * widthScaleFactor ) );
3548 featureStyle.append(
",dx:0mm" );
3549 featureStyle.append( QStringLiteral(
",dy:%1mm" ).arg( mDistance * widthScaleFactor ) );
3550 featureStyle.append(
')' );
3551 return featureStyle;
3557 && ( !mFillLineSymbol || !mFillLineSymbol->hasDataDefinedProperties() ) )
3582 Qt::PenStyle lineStyle;
3584 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
3585 if ( fillElem.isNull() )
3588 QDomElement graphicFillElem = fillElem.firstChildElement( QStringLiteral(
"GraphicFill" ) );
3589 if ( graphicFillElem.isNull() )
3592 QDomElement graphicElem = graphicFillElem.firstChildElement( QStringLiteral(
"Graphic" ) );
3593 if ( graphicElem.isNull() )
3599 if ( name != QLatin1String(
"horline" ) )
3607 double d = angleFunc.toDouble( &ok );
3616 offset = std::sqrt( std::pow( vectOffset.x(), 2 ) + std::pow( vectOffset.y(), 2 ) );
3619 double scaleFactor = 1.0;
3620 const QString uom = element.attribute( QStringLiteral(
"uom" ) );
3622 size = size * scaleFactor;
3625 auto sl = std::make_unique< QgsLinePatternFillSymbolLayer >();
3626 sl->setOutputUnit( sldUnitSize );
3627 sl->setColor( lineColor );
3629 sl->setLineAngle(
angle );
3631 sl->setDistance( size );
3634 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
3635 if ( !strokeElem.isNull() )
3641 layers.append( l.release() );
3646 return sl.release();
3746 auto layer = std::make_unique< QgsPointPatternFillSymbolLayer >();
3747 if (
properties.contains( QStringLiteral(
"distance_x" ) ) )
3749 layer->setDistanceX(
properties[QStringLiteral(
"distance_x" )].toDouble() );
3751 if (
properties.contains( QStringLiteral(
"distance_y" ) ) )
3753 layer->setDistanceY(
properties[QStringLiteral(
"distance_y" )].toDouble() );
3755 if (
properties.contains( QStringLiteral(
"displacement_x" ) ) )
3757 layer->setDisplacementX(
properties[QStringLiteral(
"displacement_x" )].toDouble() );
3759 if (
properties.contains( QStringLiteral(
"displacement_y" ) ) )
3761 layer->setDisplacementY(
properties[QStringLiteral(
"displacement_y" )].toDouble() );
3763 if (
properties.contains( QStringLiteral(
"offset_x" ) ) )
3765 layer->setOffsetX(
properties[QStringLiteral(
"offset_x" )].toDouble() );
3767 if (
properties.contains( QStringLiteral(
"offset_y" ) ) )
3769 layer->setOffsetY(
properties[QStringLiteral(
"offset_y" )].toDouble() );
3772 if (
properties.contains( QStringLiteral(
"distance_x_unit" ) ) )
3776 if (
properties.contains( QStringLiteral(
"distance_x_map_unit_scale" ) ) )
3780 if (
properties.contains( QStringLiteral(
"distance_y_unit" ) ) )
3784 if (
properties.contains( QStringLiteral(
"distance_y_map_unit_scale" ) ) )
3788 if (
properties.contains( QStringLiteral(
"displacement_x_unit" ) ) )
3792 if (
properties.contains( QStringLiteral(
"displacement_x_map_unit_scale" ) ) )
3796 if (
properties.contains( QStringLiteral(
"displacement_y_unit" ) ) )
3800 if (
properties.contains( QStringLiteral(
"displacement_y_map_unit_scale" ) ) )
3804 if (
properties.contains( QStringLiteral(
"offset_x_unit" ) ) )
3808 if (
properties.contains( QStringLiteral(
"offset_x_map_unit_scale" ) ) )
3812 if (
properties.contains( QStringLiteral(
"offset_y_unit" ) ) )
3816 if (
properties.contains( QStringLiteral(
"offset_y_map_unit_scale" ) ) )
3821 if (
properties.contains( QStringLiteral(
"random_deviation_x" ) ) )
3823 layer->setMaximumRandomDeviationX(
properties[QStringLiteral(
"random_deviation_x" )].toDouble() );
3825 if (
properties.contains( QStringLiteral(
"random_deviation_y" ) ) )
3827 layer->setMaximumRandomDeviationY(
properties[QStringLiteral(
"random_deviation_y" )].toDouble() );
3829 if (
properties.contains( QStringLiteral(
"random_deviation_x_unit" ) ) )
3833 if (
properties.contains( QStringLiteral(
"random_deviation_x_map_unit_scale" ) ) )
3837 if (
properties.contains( QStringLiteral(
"random_deviation_y_unit" ) ) )
3841 if (
properties.contains( QStringLiteral(
"random_deviation_y_map_unit_scale" ) ) )
3845 unsigned long seed = 0;
3846 if (
properties.contains( QStringLiteral(
"seed" ) ) )
3852 std::random_device rd;
3853 std::mt19937 mt(
static_cast< int >( rd() ) );
3854 std::uniform_int_distribution<> uniformDist( 1, 999999999 );
3855 seed = uniformDist( mt );
3857 layer->setSeed(
seed );
3859 if (
properties.contains( QStringLiteral(
"outline_width_unit" ) ) )
3863 if (
properties.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
3867 if (
properties.contains( QStringLiteral(
"clip_mode" ) ) )
3871 if (
properties.contains( QStringLiteral(
"coordinate_reference" ) ) )
3876 if (
properties.contains( QStringLiteral(
"angle" ) ) )
3878 layer->setAngle(
properties[QStringLiteral(
"angle" )].toDouble() );
3883 return layer.release();
3888 return QStringLiteral(
"PointPatternFill" );
3891bool QgsPointPatternFillSymbolLayer::applyPattern(
const QgsSymbolRenderContext &context, QBrush &brush,
double distanceX,
double distanceY,
3892 double displacementX,
double displacementY,
double offsetX,
double offsetY )
3899 double widthOffset = std::fmod(
3902 double heightOffset = std::fmod(
3906 if ( width > 2000 || height > 2000 )
3908 brush.setTextureImage( QImage() );
3912 QImage patternImage( width, height, QImage::Format_ARGB32 );
3913 patternImage.fill( 0 );
3914 if ( patternImage.isNull() )
3916 brush.setTextureImage( QImage() );
3921 QPainter p( &patternImage );
3924 QgsRenderContext pointRenderContext;
3939 for (
double currentX = -width; currentX <= width * 2.0; currentX += width )
3941 for (
double currentY = -height; currentY <= height * 2.0; currentY += height )
3943 mMarkerSymbol->renderPoint( QPointF( currentX + widthOffset, currentY + heightOffset ), context.
feature(), pointRenderContext );
3954 for (
double currentX = -width; currentX <= width * 2.0; currentX += width )
3956 for (
double currentY = -height / 2.0; currentY <= height * 2.0; currentY += height )
3958 mMarkerSymbol->renderPoint( QPointF( currentX + widthOffset + displacementPixelX, currentY + heightOffset ), context.
feature(), pointRenderContext );
3962 for (
double currentX = -width / 2.0; currentX <= width * 2.0; currentX += width )
3964 for (
double currentY = -height; currentY <= height * 2.0; currentY += height / 2.0 )
3966 mMarkerSymbol->renderPoint( QPointF( currentX + widthOffset + ( std::fmod( currentY, height ) != 0 ? displacementPixelX : 0 ), currentY + heightOffset - displacementPixelY ), context.
feature(), pointRenderContext );
3975 QImage transparentImage = patternImage.copy();
3977 brush.setTextureImage( transparentImage );
3981 brush.setTextureImage( patternImage );
3983 QTransform brushTransform;
3984 brush.setTransform( brushTransform );
4004 if ( !mRenderUsingMarkers )
4049 if ( !useSelectedColor && !mRenderUsingMarkers )
4099 const double widthOffset = std::fmod(
4111 const double heightOffset = std::fmod(
4137 p->setPen( QPen( Qt::NoPen ) );
4169 std::unique_ptr< QgsPolygon > shapePolygon;
4170 std::unique_ptr< QgsGeometryEngine > shapeEngine;
4177 shapePolygon = std::make_unique< QgsPolygon >();
4179 shapePolygon->setExteriorRing( fromPolygon.release() );
4182 for (
const QPolygonF &ring : *rings )
4185 shapePolygon->addInteriorRing( fromRing.release() );
4189 shapeEngine->prepareGeometry();
4196 path.addPolygon( points );
4199 for (
const QPolygonF &ring : *rings )
4201 path.addPolygon( ring );
4204 p->setClipPath( path, Qt::IntersectClip );
4210 const QRectF boundingRect = points.boundingRect();
4212 QTransform invertedRotateTransform;
4220 QTransform transform;
4221 if ( applyBrushTransform )
4224 transform.translate( -boundingRect.center().x(),
4225 -boundingRect.center().y() );
4226 transform.rotate( -
angle );
4227 transform.translate( boundingRect.center().x(),
4228 boundingRect.center().y() );
4233 transform.rotate( -
angle );
4236 const QRectF transformedBounds = transform.map( points ).boundingRect();
4237 left = transformedBounds.left() - 2 * width;
4238 top = transformedBounds.top() - 2 * height;
4239 right = transformedBounds.right() + 2 * width;
4240 bottom = transformedBounds.bottom() + 2 * height;
4241 invertedRotateTransform = transform.inverted();
4243 if ( !applyBrushTransform )
4245 left -= transformedBounds.left() - ( width * std::floor( transformedBounds.left() / width ) );
4246 top -= transformedBounds.top() - ( height * std::floor( transformedBounds.top() / height ) );
4251 left = boundingRect.left() - 2 * width;
4252 top = boundingRect.top() - 2 * height;
4253 right = boundingRect.right() + 2 * width;
4254 bottom = boundingRect.bottom() + 2 * height;
4256 if ( !applyBrushTransform )
4258 left -= boundingRect.left() - ( width * std::floor( boundingRect.left() / width ) );
4259 top -= boundingRect.top() - ( height * std::floor( boundingRect.top() / height ) );
4288 std::random_device rd;
4289 std::mt19937 mt(
seed == 0 ? rd() :
seed );
4290 std::uniform_real_distribution<> uniformDist( 0, 1 );
4296 const bool needsExpressionContext =
mMarkerSymbol->hasDataDefinedProperties();
4304 bool alternateColumn =
false;
4305 int currentCol = -3;
4306 for (
double currentX = left; currentX <= right; currentX += width, alternateColumn = !alternateColumn )
4311 if ( needsExpressionContext )
4314 bool alternateRow =
false;
4315 const double columnX = currentX + widthOffset;
4316 int currentRow = -3;
4317 for (
double currentY = top; currentY <= bottom; currentY += height, alternateRow = !alternateRow )
4322 double y = currentY + heightOffset;
4325 x += displacementPixelX;
4327 if ( !alternateColumn )
4328 y -= displacementPixelY;
4334 invertedRotateTransform.map( xx, yy, &x, &y );
4337 if ( useRandomShift )
4339 x += ( 2 * uniformDist( mt ) - 1 ) * maxRandomDeviationPixelX;
4340 y += ( 2 * uniformDist( mt ) - 1 ) * maxRandomDeviationPixelY;
4343 if ( needsExpressionContext )
4351 bool renderPoint =
true;
4359 renderPoint = shapeEngine->intersects( &p );
4369 renderPoint = shapeEngine->contains( markerBounds.
constGet() );
4371 renderPoint = shapeEngine->intersects( markerBounds.
constGet() );
4397 map.insert( QStringLiteral(
"distance_x" ), QString::number(
mDistanceX ) );
4398 map.insert( QStringLiteral(
"distance_y" ), QString::number(
mDistanceY ) );
4399 map.insert( QStringLiteral(
"displacement_x" ), QString::number(
mDisplacementX ) );
4400 map.insert( QStringLiteral(
"displacement_y" ), QString::number(
mDisplacementY ) );
4401 map.insert( QStringLiteral(
"offset_x" ), QString::number(
mOffsetX ) );
4402 map.insert( QStringLiteral(
"offset_y" ), QString::number(
mOffsetY ) );
4418 map.insert( QStringLiteral(
"random_deviation_x" ), QString::number(
mRandomDeviationX ) );
4419 map.insert( QStringLiteral(
"random_deviation_y" ), QString::number(
mRandomDeviationY ) );
4424 map.insert( QStringLiteral(
"seed" ), QString::number(
mSeed ) );
4425 map.insert( QStringLiteral(
"angle" ),
mAngle );
4446 toSld( doc, element, context );
4452 for (
int symbolLayerIdx = 0; symbolLayerIdx <
mMarkerSymbol->symbolLayerCount(); symbolLayerIdx++ )
4454 QDomElement symbolizerElem = doc.createElement( QStringLiteral(
"se:PolygonSymbolizer" ) );
4455 if ( !props.value( QStringLiteral(
"uom" ), QString() ).toString().isEmpty() )
4456 symbolizerElem.setAttribute( QStringLiteral(
"uom" ), props.value( QStringLiteral(
"uom" ), QString() ).toString() );
4457 element.appendChild( symbolizerElem );
4462 QDomElement fillElem = doc.createElement( QStringLiteral(
"se:Fill" ) );
4463 symbolizerElem.appendChild( fillElem );
4465 QDomElement graphicFillElem = doc.createElement( QStringLiteral(
"se:GraphicFill" ) );
4466 fillElem.appendChild( graphicFillElem );
4471 bool exportOk {
false };
4475 if ( ! image.isNull() )
4477 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
4478 graphicFillElem.appendChild( graphicElem );
4480 QString pngPath { info.completeSuffix().isEmpty() ? context.
exportFilePath() : context.
exportFilePath().chopped( info.completeSuffix().length() ).append( QStringLiteral(
"png" ) ) };
4481 pngPath = QgsFileUtils::uniquePath( pngPath );
4482 image.save( pngPath );
4501 symbolizerElem.appendChild( graphicMarginElem );
4505 markerLayer->writeSldMarker( doc, graphicFillElem, context );
4509 QgsDebugError( QStringLiteral(
"QgsMarkerSymbolLayer expected, %1 found. Skip it." ).arg( layer->
layerType() ) );
4513 QgsDebugError( QStringLiteral(
"Missing point pattern symbol layer. Skip it." ) );
4523 double angleRads { qDegreesToRadians(
mAngle ) };
4532 if ( displacementXPx != 0 )
4537 if ( displacementYPx != 0 )
4544 QPixmap pixmap( size );
4545 pixmap.fill( Qt::transparent );
4547 painter.begin( &pixmap );
4548 painter.setRenderHint( QPainter::Antialiasing );
4556 std::unique_ptr< QgsPointPatternFillSymbolLayer > layerClone(
clone() );
4558 layerClone->setAngle( qRadiansToDegrees( angleRads ) );
4561 layerClone->setMaximumRandomDeviationX( 0 );
4562 layerClone->setMaximumRandomDeviationY( 0 );
4564 layerClone->drawPreviewIcon( symbolContext, pixmap.size() );
4566 return pixmap.toImage();
4574 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
4575 if ( fillElem.isNull() )
4578 QDomElement graphicFillElem = fillElem.firstChildElement( QStringLiteral(
"GraphicFill" ) );
4579 if ( graphicFillElem.isNull() )
4582 QDomElement graphicElem = graphicFillElem.firstChildElement( QStringLiteral(
"Graphic" ) );
4583 if ( graphicElem.isNull() )
4587 if ( !simpleMarkerSl )
4591 layers.append( simpleMarkerSl.release() );
4593 auto marker = std::make_unique< QgsMarkerSymbol >( layers );
4596 const double markerSize { marker->size() };
4598 auto pointPatternFillSl = std::make_unique< QgsPointPatternFillSymbolLayer >();
4599 pointPatternFillSl->setSubSymbol( marker.release() );
4604 auto distanceParser = [ & ](
const QStringList & values )
4606 switch ( values.count( ) )
4611 const double v { values.at( 0 ).toDouble( &ok ) };
4614 pointPatternFillSl->setDistanceX( v * 2 + markerSize );
4615 pointPatternFillSl->setDistanceY( v * 2 + markerSize );
4622 const double vX { values.at( 1 ).toDouble( &ok ) };
4625 pointPatternFillSl->setDistanceX( vX * 2 + markerSize );
4627 const double vY { values.at( 0 ).toDouble( &ok ) };
4630 pointPatternFillSl->setDistanceY( vY * 2 + markerSize );
4637 const double vX { values.at( 1 ).toDouble( &ok ) };
4640 pointPatternFillSl->setDistanceX( vX * 2 + markerSize );
4642 const double vYt { values.at( 0 ).toDouble( &ok ) };
4645 const double vYb { values.at( 2 ).toDouble( &ok ) };
4648 pointPatternFillSl->setDistanceY( ( vYt + vYb ) + markerSize );
4656 const double vYt { values.at( 0 ).toDouble( &ok ) };
4659 const double vYb { values.at( 2 ).toDouble( &ok ) };
4662 pointPatternFillSl->setDistanceY( ( vYt + vYb ) + markerSize );
4665 const double vXr { values.at( 1 ).toDouble( &ok ) };
4668 const double vXl { values.at( 3 ).toDouble( &ok ) };
4671 pointPatternFillSl->setDistanceX( ( vXr + vXl ) + markerSize );
4682 bool distanceFromVendorOption {
false };
4684 for ( QgsStringMap::iterator it = vendorOptions.begin(); it != vendorOptions.end(); ++it )
4687 if ( it.key() == QLatin1String(
"distance" ) )
4689 distanceParser( it.value().split(
',' ) );
4690 distanceFromVendorOption =
true;
4693 else if ( it.key() == QLatin1String(
"graphic-margin" ) )
4695 distanceParser( it.value().split(
' ' ) );
4696 distanceFromVendorOption =
true;
4701 if ( ! distanceFromVendorOption && ! graphicFillElem.elementsByTagName( QStringLiteral(
"Size" ) ).isEmpty() )
4703 const QDomElement sizeElement { graphicFillElem.elementsByTagName( QStringLiteral(
"Size" ) ).at( 0 ).toElement() };
4705 const double size { sizeElement.text().toDouble( &ok ) };
4708 pointPatternFillSl->setDistanceX( size );
4709 pointPatternFillSl->setDistanceY( size );
4713 return pointPatternFillSl.release();
4795 attributes.unite(
mMarkerSymbol->usedAttributes( context ) );
4833 auto sl = std::make_unique< QgsCentroidFillSymbolLayer >();
4835 if (
properties.contains( QStringLiteral(
"point_on_surface" ) ) )
4836 sl->setPointOnSurface(
properties[QStringLiteral(
"point_on_surface" )].toInt() != 0 );
4837 if (
properties.contains( QStringLiteral(
"point_on_all_parts" ) ) )
4838 sl->setPointOnAllParts(
properties[QStringLiteral(
"point_on_all_parts" )].toInt() != 0 );
4839 if (
properties.contains( QStringLiteral(
"clip_points" ) ) )
4840 sl->setClipPoints(
properties[QStringLiteral(
"clip_points" )].toInt() != 0 );
4841 if (
properties.contains( QStringLiteral(
"clip_on_current_part_only" ) ) )
4842 sl->setClipOnCurrentPartOnly(
properties[QStringLiteral(
"clip_on_current_part_only" )].toInt() != 0 );
4844 sl->restoreOldDataDefinedProperties(
properties );
4846 return sl.release();
4851 return QStringLiteral(
"CentroidFill" );
4879 part.exterior = points;
4881 part.rings = *rings;
4889 mCurrentParts << part;
4894 const double prevOpacity =
mMarker->opacity();
4898 mMarker->setOpacity( prevOpacity );
4907 mCurrentParts.clear();
4914 const double prevOpacity =
mMarker->opacity();
4920 mMarker->setOpacity( prevOpacity );
4925void QgsCentroidFillSymbolLayer::render(
QgsRenderContext &context,
const QVector<QgsCentroidFillSymbolLayer::Part> &parts,
const QgsFeature &feature,
bool selected )
4934 QVector< QgsGeometry > geometryParts;
4935 geometryParts.reserve( parts.size() );
4936 QPainterPath globalPath;
4939 int maxAreaPartIdx = 0;
4941 for (
int i = 0; i < parts.size(); i++ )
4943 const Part part = parts[i];
4946 if ( !geom.
isNull() && !part.rings.empty() )
4952 int area = poly->
area();
4954 if ( area > maxArea )
4964 globalPath.addPolygon( part.exterior );
4965 for (
const QPolygonF &ring : part.rings )
4967 globalPath.addPolygon( ring );
4972 for (
int i = 0; i < parts.size(); i++ )
4977 const Part part = parts[i];
4985 path.addPolygon( part.exterior );
4986 for (
const QPolygonF &ring : part.rings )
4988 path.addPolygon( ring );
4997 context.
painter()->setClipPath( path );
5004 mMarker->renderPoint( centroid, feature.
isValid() ? &feature :
nullptr, context, -1, selected );
5017 map[QStringLiteral(
"point_on_surface" )] = QString::number(
mPointOnSurface );
5018 map[QStringLiteral(
"point_on_all_parts" )] = QString::number(
mPointOnAllParts );
5019 map[QStringLiteral(
"clip_points" )] = QString::number(
mClipPoints );
5026 auto x = std::make_unique< QgsCentroidFillSymbolLayer >();
5029 x->setSubSymbol(
mMarker->clone() );
5043 toSld( doc, element, context );
5051 return mMarker->toSld( doc, element, context );
5061 layers.append( l.release() );
5062 auto marker = std::make_unique<QgsMarkerSymbol>( layers );
5064 auto sl = std::make_unique< QgsCentroidFillSymbolLayer >();
5065 sl->setSubSymbol( marker.release() );
5066 sl->setPointOnAllParts(
false );
5067 return sl.release();
5094 attributes.unite(
mMarker->usedAttributes( context ) );
5117 mMarker->setOutputUnit( unit );
5134 return mMarker->usesMapUnits();
5143 mMarker->setMapUnitScale( scale );
5151 return mMarker->mapUnitScale();
5178 if (
properties.contains( QStringLiteral(
"imageFile" ) ) )
5180 imagePath =
properties[QStringLiteral(
"imageFile" )].toString();
5182 if (
properties.contains( QStringLiteral(
"coordinate_mode" ) ) )
5186 if (
properties.contains( QStringLiteral(
"alpha" ) ) )
5188 alpha =
properties[QStringLiteral(
"alpha" )].toDouble();
5190 if (
properties.contains( QStringLiteral(
"offset" ) ) )
5194 if (
properties.contains( QStringLiteral(
"angle" ) ) )
5198 if (
properties.contains( QStringLiteral(
"width" ) ) )
5202 auto symbolLayer = std::make_unique< QgsRasterFillSymbolLayer >( imagePath );
5203 symbolLayer->setCoordinateMode( mode );
5204 symbolLayer->setOpacity( alpha );
5205 symbolLayer->setOffset(
offset );
5206 symbolLayer->setAngle(
angle );
5207 symbolLayer->setWidth(
width );
5208 if (
properties.contains( QStringLiteral(
"offset_unit" ) ) )
5212 if (
properties.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
5216 if (
properties.contains( QStringLiteral(
"width_unit" ) ) )
5220 if (
properties.contains( QStringLiteral(
"width_map_unit_scale" ) ) )
5225 if (
properties.contains( QStringLiteral(
"height" ) ) )
5227 symbolLayer->setHeight(
properties[QStringLiteral(
"height" )].toDouble() );
5230 symbolLayer->restoreOldDataDefinedProperties(
properties );
5232 return symbolLayer.release();
5237 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
5238 if ( fillElem.isNull() )
5241 QDomElement graphicFillElem = fillElem.firstChildElement( QStringLiteral(
"GraphicFill" ) );
5242 if ( graphicFillElem.isNull() )
5245 QDomElement graphicElem = graphicFillElem.firstChildElement( QStringLiteral(
"Graphic" ) );
5246 if ( graphicElem.isNull() )
5249 QString path, mimeType;
5257 if ( ! QFile::exists( path ) )
5262 auto sl = std::make_unique< QgsRasterFillSymbolLayer>( path );
5264 return sl.release();
5269 QVariantMap::iterator it =
properties.find( QStringLiteral(
"imageFile" ) );
5273 it.value() = pathResolver.
writePath( it.value().toString() );
5275 it.value() = pathResolver.
readPath( it.value().toString() );
5287 return QStringLiteral(
"RasterFill" );
5303 QPointF
offset = mOffset;
5321 QRectF boundingRect = points.boundingRect();
5322 mBrush.setTransform(
mBrush.transform().translate( boundingRect.left() -
mBrush.transform().dx(),
5323 boundingRect.top() -
mBrush.transform().dy() ) );
5335 applyPattern(
mBrush, mImageFilePath, mWidth, mHeight, mOpacity * context.
opacity(), context );
5346 map[QStringLiteral(
"imageFile" )] = mImageFilePath;
5347 map[QStringLiteral(
"coordinate_mode" )] = QString::number(
static_cast< int >( mCoordinateMode ) );
5348 map[QStringLiteral(
"alpha" )] = QString::number( mOpacity );
5352 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
5354 map[QStringLiteral(
"width" )] = QString::number( mWidth );
5355 map[QStringLiteral(
"height" )] = QString::number( mHeight );
5364 auto sl = std::make_unique< QgsRasterFillSymbolLayer >( mImageFilePath );
5365 sl->setCoordinateMode( mCoordinateMode );
5366 sl->setOpacity( mOpacity );
5367 sl->setOffset( mOffset );
5368 sl->setOffsetUnit( mOffsetUnit );
5369 sl->setOffsetMapUnitScale( mOffsetMapUnitScale );
5371 sl->setWidth( mWidth );
5372 sl->setHeight( mHeight );
5373 sl->setSizeUnit( mSizeUnit );
5374 sl->setSizeMapUnitScale( mSizeMapUnitScale );
5378 return sl.release();
5383 return context.
convertToPainterUnits( std::max( std::fabs( mOffset.x() ), std::fabs( mOffset.y() ) ), mOffsetUnit, mOffsetMapUnitScale );
5406 mImageFilePath = imagePath;
5411 mCoordinateMode = mode;
5430 if ( !hasWidthExpression && !hasHeightExpression && !hasAngleExpression && !hasOpacityExpression && !hasFileExpression )
5436 if ( hasAngleExpression )
5444 if ( !hasWidthExpression && !hasHeightExpression && !hasOpacityExpression && !hasFileExpression )
5449 double width = mWidth;
5450 if ( hasWidthExpression )
5456 if ( hasHeightExpression )
5462 if ( hasOpacityExpression )
5467 QString file = mImageFilePath;
5468 if ( hasFileExpression )
5481void QgsRasterFillSymbolLayer::applyPattern( QBrush &brush,
const QString &imageFilePath,
const double width,
const double height,
const double alpha,
const QgsSymbolRenderContext &context )
5483 double imageWidth = 0;
5484 double imageHeight = 0;
5499 if ( originalSize.isEmpty() )
5502 imageWidth = (
width * originalSize.width() ) / 100.0;
5505 if (
static_cast< int >( imageWidth ) < 1 || 10000.0 < imageWidth )
5518 if ( !originalSize.isValid() )
5521 if ( originalSize.isEmpty() )
5524 imageHeight = (
height * originalSize.height() ) / 100.0;
5527 if (
static_cast< int >( imageHeight ) < 1 || 10000.0 < imageHeight )
5532 if (
width == 0 && imageHeight > 0 )
5534 if ( !originalSize.isValid() )
5537 imageWidth = imageHeight * originalSize.width() / originalSize.height();
5539 else if (
height == 0 && imageWidth > 0 )
5541 if ( !originalSize.isValid() )
5544 imageHeight = imageWidth * originalSize.height() / originalSize.width();
5546 if ( imageWidth == 0 || imageHeight == 0 )
5548 if ( !originalSize.isValid() )
5551 imageWidth = originalSize.width();
5552 imageHeight = originalSize.height();
5560 brush.setTextureImage( img );
5569 : mCountMethod( method )
5582 const int pointCount =
properties.value( QStringLiteral(
"point_count" ), QStringLiteral(
"10" ) ).toInt();
5583 const double densityArea =
properties.value( QStringLiteral(
"density_area" ), QStringLiteral(
"250.0" ) ).toDouble();
5585 unsigned long seed = 0;
5586 if (
properties.contains( QStringLiteral(
"seed" ) ) )
5592 std::random_device rd;
5593 std::mt19937 mt(
static_cast< int >( rd() ) );
5594 std::uniform_int_distribution<> uniformDist( 1, 999999999 );
5595 seed = uniformDist( mt );
5600 if (
properties.contains( QStringLiteral(
"density_area_unit" ) ) )
5602 if (
properties.contains( QStringLiteral(
"density_area_unit_scale" ) ) )
5605 if (
properties.contains( QStringLiteral(
"clip_points" ) ) )
5607 sl->setClipPoints(
properties[QStringLiteral(
"clip_points" )].toInt() );
5610 return sl.release();
5615 return QStringLiteral(
"RandomMarkerFill" );
5620 mMarker->setColor(
color );
5626 return mMarker ? mMarker->color() :
mColor;
5643 part.exterior = points;
5645 part.rings = *rings;
5647 if ( mRenderingFeature )
5651 mFeatureSymbolOpacity = context.
opacity();
5652 mCurrentParts << part;
5657 const double prevOpacity = mMarker->opacity();
5658 mMarker->setOpacity( mMarker->opacity() * context.
opacity() );
5661 mMarker->setOpacity( prevOpacity );
5665void QgsRandomMarkerFillSymbolLayer::render(
QgsRenderContext &context,
const QVector<QgsRandomMarkerFillSymbolLayer::Part> &parts,
const QgsFeature &feature,
bool selected )
5674 QVector< QgsGeometry > geometryParts;
5675 geometryParts.reserve( parts.size() );
5678 for (
const Part &part : parts )
5681 if ( !geom.
isNull() && !part.rings.empty() )
5684 for (
const QPolygonF &ring : part.rings )
5692 geom = geom.
buffer( 0, 0 );
5694 geometryParts << geom;
5698 path.addPolygon( part.exterior );
5699 for (
const QPolygonF &ring : part.rings )
5701 path.addPolygon( ring );
5706 const QgsGeometry geom = geometryParts.count() != 1 ?
QgsGeometry::unaryUnion( geometryParts ) : geometryParts.at( 0 );
5711 context.
painter()->setClipPath( path );
5715 int count = mPointCount;
5718 context.expressionContext().setOriginalValueVariable( count );
5719 count = mDataDefinedProperties.valueAsInt( QgsSymbolLayer::Property::PointCount, context.expressionContext(), count );
5722 switch ( mCountMethod )
5734 count = std::max( 0.0, std::ceil( count * ( geom.
area() /
densityArea ) ) );
5741 unsigned long seed = mSeed;
5744 context.expressionContext().setOriginalValueVariable( static_cast< unsigned long long >( seed ) );
5745 seed = mDataDefinedProperties.valueAsInt( QgsSymbolLayer::Property::RandomSeed, context.expressionContext(), seed );
5752 std::sort( randomPoints.begin(), randomPoints.end(), [](
const QgsPointXY & a,
const QgsPointXY & b )->bool
5754 return a.y() < b.y();
5757 QgsExpressionContextScope *scope =
new QgsExpressionContextScope();
5758 QgsExpressionContextScopePopper scopePopper( context.
expressionContext(), scope );
5760 const bool needsExpressionContext = mMarker->hasDataDefinedProperties();
5765 for (
const QgsPointXY &p : std::as_const( randomPoints ) )
5767 if ( needsExpressionContext )
5769 mMarker->renderPoint( QPointF( p.x(), p.y() ), feature.
isValid() ? &feature :
nullptr, context, -1, selected );
5783 map.insert( QStringLiteral(
"count_method" ), QString::number(
static_cast< int >( mCountMethod ) ) );
5784 map.insert( QStringLiteral(
"point_count" ), QString::number( mPointCount ) );
5785 map.insert( QStringLiteral(
"density_area" ), QString::number( mDensityArea ) );
5788 map.insert( QStringLiteral(
"seed" ), QString::number( mSeed ) );
5789 map.insert( QStringLiteral(
"clip_points" ), QString::number( mClipPoints ) );
5795 auto res = std::make_unique< QgsRandomMarkerFillSymbolLayer >( mPointCount, mCountMethod, mDensityArea, mSeed );
5798 res->setDensityAreaUnit( mDensityAreaUnit );
5799 res->setDensityAreaUnitScale( mDensityAreaUnitScale );
5800 res->mClipPoints = mClipPoints;
5801 res->setSubSymbol( mMarker->clone() );
5804 return res.release();
5827 return mMarker.get();
5839 mColor = mMarker->color();
5848 attributes.unite( mMarker->usedAttributes( context ) );
5857 if ( mMarker && mMarker->hasDataDefinedProperties() )
5894 return mCountMethod;
5899 mCountMethod = method;
5904 return mDensityArea;
5909 mDensityArea = area;
5916 mRenderingFeature =
true;
5917 mCurrentParts.clear();
5922 mRenderingFeature =
false;
5924 const double prevOpacity = mMarker->opacity();
5925 mMarker->setOpacity( mMarker->opacity() * mFeatureSymbolOpacity );
5927 render( context, mCurrentParts, feature,
false );
5929 mFeatureSymbolOpacity = 1;
5930 mMarker->setOpacity( prevOpacity );
5938 mDensityAreaUnit = unit;
5941 mMarker->setOutputUnit( unit );
5949 return mMarker->outputUnit();
5958 return mMarker->usesMapUnits();
5967 mMarker->setMapUnitScale( scale );
5975 return mMarker->mapUnitScale();
@ PreferVector
Prefer vector-based rendering, when the result will still be visually near-identical to a raster-base...
MarkerClipMode
Marker clipping modes.
@ CompletelyWithin
Render complete markers wherever the completely fall within the polygon shape.
@ NoClipping
No clipping, render complete markers.
@ Shape
Clip to polygon shape.
@ CentroidWithin
Render complete markers wherever their centroid falls within the polygon shape.
@ IsSymbolLayerSubSymbol
Symbol is being rendered as a sub-symbol of a QgsSymbolLayer.
LineClipMode
Line clipping modes.
@ NoClipping
Lines are not clipped, will extend to shape's bounding box.
@ ClipPainterOnly
Applying clipping on the painter only (i.e. line endpoints will coincide with polygon bounding box,...
@ ClipToIntersection
Clip lines to intersection with polygon shape (slower) (i.e. line endpoints will coincide with polygo...
GradientColorSource
Gradient color sources.
@ ColorRamp
Gradient color ramp.
@ SimpleTwoColor
Simple two color gradient.
@ CanCalculateMaskGeometryPerFeature
If present, indicates that mask geometry can safely be calculated per feature for the symbol layer....
GradientSpread
Gradient spread options, which control how gradients are rendered outside of their start and end poin...
@ Reflect
Reflect gradient.
@ Pad
Pad out gradient using colors at endpoint of gradient.
@ Png
Export complex styles to separate PNG files for better compatibility with OGC servers.
PointCountMethod
Methods which define the number of points randomly filling a polygon.
@ Absolute
The point count is used as an absolute count of markers.
@ DensityBased
The point count is part of a marker density count.
QFlags< SymbolLayerFlag > SymbolLayerFlags
Symbol layer flags.
RenderUnit
Rendering size units.
@ Percentage
Percentage of another measurement (e.g., canvas size, feature size).
@ Unknown
Mixed or unknown units.
@ MetersInMapUnits
Meters value as Map units.
@ RenderingSubSymbol
Set whenever a sub-symbol of a parent symbol is currently being rendered. Can be used during symbol a...
@ RenderSymbolPreview
The render is for a symbol preview only and map based properties may not be available,...
@ RenderMapTile
Draw map such that there are no problems between adjacent tiles.
@ RenderLayerTree
The render is for a layer tree display where map based properties are not available and where avoidan...
@ HighQualityImageTransforms
Enable high quality image transformations, which results in better appearance of scaled or rotated ra...
@ RenderBlocking
Render and load remote sources in the same thread to ensure rendering remote sources (svg and images)...
GradientType
Gradient types.
@ Conical
Conical (polar) gradient.
@ Radial
Radial (circular) gradient.
QFlags< SymbolRenderHint > SymbolRenderHints
Symbol render hints.
SymbolCoordinateReference
Symbol coordinate reference modes.
@ Feature
Relative to feature/shape being rendered.
@ Viewport
Relative to the whole viewport/output device.
QColor valueAsColor(int key, const QgsExpressionContext &context, const QColor &defaultColor=QColor(), bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a color.
bool valueAsBool(int key, const QgsExpressionContext &context, bool defaultValue=false, bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as an boolean.
static QgsImageCache * imageCache()
Returns the application's image cache, used for caching resampled versions of raster images.
static QgsSvgCache * svgCache()
Returns the application's SVG cache, used for caching SVG images and handling parameter replacement w...
static QgsSymbolLayer * createFromSld(QDomElement &element)
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
QgsSymbol * subSymbol() override
Returns the symbol's sub symbol, if present.
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
void setMapUnitScale(const QgsMapUnitScale &scale) override
bool canCauseArtifactsBetweenAdjacentTiles() const override
Returns true if the symbol layer rendering can cause visible artifacts across a single feature when t...
bool setSubSymbol(QgsSymbol *symbol) final
Sets layer's subsymbol. takes ownership of the passed symbol.
bool pointOnSurface() const
QgsMapUnitScale mapUnitScale() const override
void startFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called before the layer will be rendered for a particular feature.
std::unique_ptr< QgsMarkerSymbol > mMarker
QString layerType() const override
Returns a string that represents this layer type.
void setColor(const QColor &color) override
Sets the "representative" color for the symbol layer.
bool pointOnAllParts() const
Returns whether a point is drawn for all parts or only on the biggest part of multi-part features.
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
bool hasDataDefinedProperties() const override
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
void stopFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called after the layer has been rendered for a particular feature.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
bool clipPoints() const
Returns true if point markers should be clipped to the polygon boundary.
QgsCentroidFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
Q_DECL_DEPRECATED void toSld(QDomDocument &doc, QDomElement &element, const QVariantMap &props) const override
Saves the symbol layer as SLD.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsCentroidFillSymbolLayer using the specified properties map containing symbol propert...
~QgsCentroidFillSymbolLayer() override
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
double mFeatureSymbolOpacity
QgsCentroidFillSymbolLayer()
QColor color() const override
Returns the "representative" color of the symbol layer.
bool clipOnCurrentPartOnly() const
Returns true if point markers should be clipped to the current part boundary only.
bool mClipOnCurrentPartOnly
Abstract base class for color ramps.
virtual QColor color(double value) const =0
Returns the color corresponding to a specified value.
virtual QString type() const =0
Returns a string representing the color ramp type.
static QColor colorFromString(const QString &string)
Decodes a string into a color value.
static QString colorToString(const QColor &color)
Encodes a color into a string value.
static QgsColorRamp * create(const QVariantMap &properties=QVariantMap())
Creates the symbol layer.
static QString typeString()
Returns the string identifier for QgsCptCityColorRamp.
double area() const override
Returns the planar, 2-dimensional area of the geometry.
Exports QGIS layers to the DXF format.
static double mapUnitScaleFactor(double scale, Qgis::RenderUnit symbolUnits, Qgis::DistanceUnit mapUnits, double mapUnitsPerPixel=1.0)
Returns scale factor for conversion to map units.
Qgis::DistanceUnit mapUnits() const
Retrieve map units.
double symbologyScale() const
Returns the reference scale for output.
RAII class to pop scope from an expression context on destruction.
Single scope for storing variables and functions for use within a QgsExpressionContext.
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
static const QString EXPR_GEOMETRY_POINT_NUM
Inbuilt variable name for point number variable.
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for the context.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
bool isValid() const
Returns the validity of this feature.
bool isCanceled() const
Tells whether the operation has been canceled already.
void _renderPolygon(QPainter *p, const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context)
Default method to render polygon.
double angle() const
Returns the rotation angle of the fill symbol, in degrees clockwise.
A geometry is the spatial representation of a feature.
QVector< QgsPointXY > randomPointsInPolygon(int count, const std::function< bool(const QgsPointXY &) > &acceptPoint, unsigned long seed=0, QgsFeedback *feedback=nullptr, int maxTriesPerPoint=0) const
Returns a list of count random points generated inside a (multi)polygon geometry (if acceptPoint is s...
static QgsGeometry fromRect(const QgsRectangle &rect)
Creates a new geometry from a QgsRectangle.
static QgsGeometry fromQPolygonF(const QPolygonF &polygon)
Construct geometry from a QPolygonF.
QgsAbstractGeometry * get()
Returns a modifiable (non-const) reference to the underlying abstract geometry primitive.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
bool isGeosValid(Qgis::GeometryValidityFlags flags=Qgis::GeometryValidityFlags()) const
Checks validity of the geometry using GEOS.
double area() const
Returns the planar, 2-dimensional area of the geometry.
QgsGeometry buffer(double distance, int segments) const
Returns a buffer region around this geometry having the given width and with a specified number of se...
static QgsGeometry unaryUnion(const QVector< QgsGeometry > &geometries, const QgsGeometryParameters ¶meters=QgsGeometryParameters())
Compute the unary union on a list of geometries.
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometry *geometry, double precision=0.0, Qgis::GeosCreationFlags flags=Qgis::GeosCreationFlag::SkipEmptyInteriorRings)
Creates and returns a new geometry engine representing the specified geometry using precision on a gr...
static QgsColorRamp * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsColorRamp from a map of properties.
static QString typeString()
Returns the string identifier for QgsGradientColorRamp.
void addStopsToGradient(QGradient *gradient, double opacity=1) const
Copy color ramp stops to a QGradient.
void setColorRamp(QgsColorRamp *ramp)
Sets the color ramp used for the gradient fill.
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
QColor color2() const
Returns the color for endpoint of gradient, only used if the gradient color type is set to SimpleTwoC...
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
bool canCauseArtifactsBetweenAdjacentTiles() const override
Returns true if the symbol layer rendering can cause visible artifacts across a single feature when t...
QgsGradientFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
QgsMapUnitScale mapUnitScale() const override
bool mReferencePoint1IsCentroid
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
Qgis::SymbolCoordinateReference coordinateMode() const
Returns the coordinate mode for gradient, which controls how the gradient stops are positioned.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
Qgis::SymbolCoordinateReference mCoordinateMode
QgsGradientFillSymbolLayer(const QColor &color=DEFAULT_SIMPLEFILL_COLOR, const QColor &color2=Qt::white, Qgis::GradientColorSource gradientColorType=Qgis::GradientColorSource::SimpleTwoColor, Qgis::GradientType gradientType=Qgis::GradientType::Linear, Qgis::SymbolCoordinateReference coordinateMode=Qgis::SymbolCoordinateReference::Feature, Qgis::GradientSpread gradientSpread=Qgis::GradientSpread::Pad)
Constructor for QgsGradientFillSymbolLayer.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsGradientFillSymbolLayer using the specified properties map containing symbol propert...
void setMapUnitScale(const QgsMapUnitScale &scale) override
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
Qgis::GradientSpread mGradientSpread
~QgsGradientFillSymbolLayer() override
Qgis::GradientType mGradientType
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QPointF referencePoint1() const
Returns the starting point of gradient fill, in the range [0,0] - [1,1].
Qgis::GradientSpread gradientSpread() const
Returns the gradient spread mode, which controls how the gradient behaves outside of the predefined s...
bool mReferencePoint2IsCentroid
QgsMapUnitScale mOffsetMapUnitScale
Qgis::GradientColorSource gradientColorType() const
Returns the gradient color mode, which controls how gradient color stops are created.
QPointF offset() const
Returns the offset by which polygons will be translated during rendering.
Qgis::GradientColorSource mGradientColorType
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
Qgis::SymbolLayerFlags flags() const override
Returns flags which control the symbol layer's behavior.
QString layerType() const override
Returns a string that represents this layer type.
Qgis::RenderUnit mOffsetUnit
Qgis::GradientType gradientType() const
Returns the type of gradient, e.g., linear or radial.
QPointF referencePoint2() const
Returns the end point of gradient fill, in the range [0,0] - [1,1].
std::unique_ptr< QgsColorRamp > mGradientRamp
QSize originalSize(const QString &path, bool blocking=false) const
Returns the original size (in pixels) of the image at the specified path.
QImage pathAsImage(const QString &path, const QSize size, const bool keepAspectRatio, const double opacity, bool &fitsInCache, bool blocking=false, double targetDpi=96, int frameNumber=-1, bool *isMissing=nullptr)
Returns the specified path rendered as an image.
QgsMapUnitScale mStrokeWidthMapUnitScale
QgsImageFillSymbolLayer()
Qgis::SymbolCoordinateReference coordinateReference() const
Returns the coordinate reference mode for fill which controls how the top left corner of the image fi...
double mStrokeWidth
Stroke width.
Qgis::SymbolCoordinateReference mCoordinateReference
double dxfWidth(const QgsDxfExport &e, QgsSymbolRenderContext &context) const override
Gets line width.
QgsMapUnitScale mapUnitScale() const override
Qt::PenStyle dxfPenStyle() const override
Gets pen style.
Qgis::RenderUnit mStrokeWidthUnit
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
void setMapUnitScale(const QgsMapUnitScale &scale) override
virtual void applyDataDefinedSettings(QgsSymbolRenderContext &context)
Applies data defined settings prior to generating the fill symbol brush.
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
~QgsImageFillSymbolLayer() override
virtual bool applyBrushTransformFromContext(QgsSymbolRenderContext *context=nullptr) const
Returns true if the image brush should be transformed using the render context's texture origin.
static void multiplyOpacity(QImage &image, double factor, QgsFeedback *feedback=nullptr)
Multiplies opacity of image pixel values by a factor.
static void stackBlur(QImage &image, int radius, bool alphaOnly=false, QgsFeedback *feedback=nullptr)
Performs a stack blur on an image.
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
QgsMapUnitScale mapUnitScale() const override
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
QString layerType() const override
Returns a string that represents this layer type.
QgsLinePatternFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
void stopFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called after the layer has been rendered for a particular feature.
void startFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called before the layer will be rendered for a particular feature.
QColor color() const override
Returns the "representative" color of the symbol layer.
Q_DECL_DEPRECATED void toSld(QDomDocument &doc, QDomElement &element, const QVariantMap &props) const override
Saves the symbol layer as SLD.
double lineWidth() const
Returns the width of the line subsymbol used to render the parallel lines in the fill.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
void setMapUnitScale(const QgsMapUnitScale &scale) override
Qgis::LineClipMode clipMode() const
Returns the line clipping mode, which defines how lines are clipped at the edges of shapes.
double lineAngle() const
Returns the angle for the parallel lines used to fill the symbol.
void setLineWidth(double w)
Sets the width of the line subsymbol used to render the parallel lines in the fill.
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
void applyDataDefinedSettings(QgsSymbolRenderContext &context) override
Applies data defined settings prior to generating the fill symbol brush.
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer's subsymbol. takes ownership of the passed symbol.
QgsSymbol * subSymbol() override
Returns the symbol's sub symbol, if present.
bool hasDataDefinedProperties() const override
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
void setColor(const QColor &c) override
Sets the "representative" color for the symbol layer.
QImage toTiledPatternImage() const override
Renders the symbol layer as an image that can be used as a seamless pattern fill for polygons,...
double offset() const
Returns the offset distance for lines within the fill, which is the distance to offset the parallel l...
QgsLinePatternFillSymbolLayer()
double distance() const
Returns the distance between lines in the fill pattern.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QString ogrFeatureStyleWidth(double widthScaleFactor) const
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
~QgsLinePatternFillSymbolLayer() override
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
static QgsSymbolLayer * createFromSld(QDomElement &element)
Creates a new QgsLinePatternFillSymbolLayer from a SLD element.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsLinePatternFillSymbolLayer from a properties map.
Line string geometry type, with support for z-dimension and m-values.
static std::unique_ptr< QgsLineString > fromQPolygonF(const QPolygonF &polygon)
Returns a new linestring from a QPolygonF polygon input.
QPolygonF asQPolygonF() const override
Returns a QPolygonF representing the points.
A line symbol type, for rendering LineString and MultiLineString geometries.
double mapUnitsPerPixel() const
Returns the current map units per pixel.
Struct for storing maximum and minimum scales for measurements in map units.
Abstract base class for marker symbol layers.
A marker symbol type, for rendering Point and MultiPoint geometries.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true, const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE())
Adds a message to the log instance (and creates it if necessary).
Resolves relative paths into absolute paths and vice versa.
QString writePath(const QString &filename) const
Prepare a filename to save it to the project file.
QString readPath(const QString &filename) const
Turn filename read from the project file to an absolute path.
QgsMapUnitScale mapUnitScale() const override
QgsMapUnitScale mDisplacementYMapUnitScale
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
QgsMapUnitScale mDisplacementXMapUnitScale
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
double distanceX() const
Returns the horizontal distance between rendered markers in the fill.
QgsMapUnitScale mDistanceYMapUnitScale
QImage toTiledPatternImage() const override
Renders the symbol layer as an image that can be used as a seamless pattern fill for polygons,...
double displacementY() const
Returns the vertical displacement for odd numbered columns in the pattern.
void setColor(const QColor &c) override
Sets the "representative" color for the symbol layer.
Qgis::RenderUnit mDistanceXUnit
void startFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called before the layer will be rendered for a particular feature.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsPointPatternFillSymbolLayer using the specified properties map containing symbol pro...
unsigned long seed() const
Returns the random number seed to use when randomly shifting points, or 0 if a truly random sequence ...
Qgis::RenderUnit mDisplacementYUnit
Qgis::MarkerClipMode clipMode() const
Returns the marker clipping mode, which defines how markers are clipped at the edges of shapes.
bool hasDataDefinedProperties() const override
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
double offsetY() const
Returns the vertical offset values for points in the pattern.
QgsSymbol * subSymbol() override
Returns the symbol's sub symbol, if present.
QgsMapUnitScale mDistanceXMapUnitScale
void setMapUnitScale(const QgsMapUnitScale &scale) override
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
QString layerType() const override
Returns a string that represents this layer type.
void applyDataDefinedSettings(QgsSymbolRenderContext &context) override
Applies data defined settings prior to generating the fill symbol brush.
Qgis::RenderUnit mRandomDeviationXUnit
Qgis::RenderUnit mOffsetXUnit
Qgis::RenderUnit mDistanceYUnit
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
QgsMapUnitScale mOffsetXMapUnitScale
void stopFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called after the layer has been rendered for a particular feature.
Qgis::RenderUnit mOffsetYUnit
QColor color() const override
Returns the "representative" color of the symbol layer.
Qgis::RenderUnit mRandomDeviationYUnit
QgsPointPatternFillSymbolLayer()
QgsMapUnitScale mRandomDeviationXMapUnitScale
Q_DECL_DEPRECATED void toSld(QDomDocument &doc, QDomElement &element, const QVariantMap &props) const override
Saves the symbol layer as SLD.
double offsetX() const
Returns the horizontal offset values for points in the pattern.
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
Qgis::RenderUnit mDisplacementXUnit
std::unique_ptr< QgsMarkerSymbol > mMarkerSymbol
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
QgsPointPatternFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
QgsMapUnitScale mRandomDeviationYMapUnitScale
double displacementX() const
Returns the horizontal displacement for odd numbered rows in the pattern.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
~QgsPointPatternFillSymbolLayer() override
QgsMapUnitScale mOffsetYMapUnitScale
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer's subsymbol. takes ownership of the passed symbol.
double distanceY() const
Returns the vertical distance between rendered markers in the fill.
void setClipMode(Qgis::MarkerClipMode mode)
Sets the marker clipping mode, which defines how markers are clipped at the edges of shapes.
static QgsSymbolLayer * createFromSld(QDomElement &element)
bool mMarkerSymbolRenderStarted
Point geometry type, with support for z-dimension and m-values.
void addInteriorRing(QgsCurve *ring) override
Adds an interior ring to the geometry (takes ownership).
static QgsProject * instance()
Returns the QgsProject singleton instance.
QgsPathResolver pathResolver() const
Returns path resolver object with considering whether the project uses absolute or relative paths and...
bool isActive(int key) const final
Returns true if the collection contains an active property with the specified key.
static QVariantMap propertyMapToVariantMap(const QMap< QString, QgsProperty > &propertyMap)
Convert a map of QgsProperty to a map of QVariant This is useful to save a map of properties.
static QMap< QString, QgsProperty > variantMapToPropertyMap(const QVariantMap &variantMap)
Convert a map of QVariant to a map of QgsProperty This is useful to restore a map of properties.
~QgsRandomMarkerFillSymbolLayer() override
bool setSubSymbol(QgsSymbol *symbol) final
Sets layer's subsymbol. takes ownership of the passed symbol.
int pointCount() const
Returns the count of random points to render in the fill.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
void startFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called before the layer will be rendered for a particular feature.
QgsRandomMarkerFillSymbolLayer(int pointCount=10, Qgis::PointCountMethod method=Qgis::PointCountMethod::Absolute, double densityArea=250.0, unsigned long seed=0)
Constructor for QgsRandomMarkerFillSymbolLayer, with the specified pointCount.
unsigned long seed() const
Returns the random number seed to use when generating points, or 0 if a truly random sequence will be...
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsRandomMarkerFillSymbolLayer using the specified properties map containing symbol pro...
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
QString layerType() const override
Returns a string that represents this layer type.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
QgsRandomMarkerFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
void setMapUnitScale(const QgsMapUnitScale &scale) override
bool hasDataDefinedProperties() const override
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
void stopFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called after the layer has been rendered for a particular feature.
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
void setCountMethod(Qgis::PointCountMethod method)
Sets the count method used to randomly fill the polygon.
bool clipPoints() const
Returns true if point markers should be clipped to the polygon boundary.
bool canCauseArtifactsBetweenAdjacentTiles() const override
Returns true if the symbol layer rendering can cause visible artifacts across a single feature when t...
void setClipPoints(bool clipped)
Sets whether point markers should be clipped to the polygon boundary.
QgsSymbol * subSymbol() override
Returns the symbol's sub symbol, if present.
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
QColor color() const override
Returns the "representative" color of the symbol layer.
void setSeed(unsigned long seed)
Sets the random number seed to use when generating points, or 0 if a truly random sequence will be us...
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
void setPointCount(int count)
Sets the count of random points to render in the fill.
Qgis::PointCountMethod countMethod() const
Returns the count method used to randomly fill the polygon.
double densityArea() const
Returns the density area used to count the number of points to randomly fill the polygon.
bool rendersIdenticallyTo(const QgsSymbolLayer *other) const override
Returns true if this symbol layer will always render identically to an other symbol layer.
void setColor(const QColor &color) override
Sets the "representative" color for the symbol layer.
void setDensityArea(double area)
Sets the density area used to count the number of points to randomly fill the polygon.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QgsMapUnitScale mapUnitScale() const override
void applyDataDefinedSettings(QgsSymbolRenderContext &context) override
Applies data defined settings prior to generating the fill symbol brush.
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
double width() const
Returns the width used for scaling the image used in the fill.
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
Qgis::SymbolLayerFlags flags() const override
Returns flags which control the symbol layer's behavior.
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
static QgsSymbolLayer * createFromSld(QDomElement &element)
Creates a new QgsRasterFillSymbolLayer from a SLD element.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsRasterFillSymbolLayer from a properties map.
QString layerType() const override
Returns a string that represents this layer type.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QgsRasterFillSymbolLayer(const QString &imageFilePath=QString())
Constructor for QgsRasterFillSymbolLayer, using a raster fill from the specified imageFilePath.
double opacity() const
Returns the opacity for the raster image used in the fill.
~QgsRasterFillSymbolLayer() override
void setOpacity(double opacity)
Sets the opacity for the raster image used in the fill.
QColor color() const override
Returns the "representative" color of the symbol layer.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
QString imageFilePath() const
The path to the raster image used for the fill.
void setImageFilePath(const QString &imagePath)
Sets the path to the raster image used for the fill.
double height() const
Returns the height used for scaling the image used in the fill.
static void resolvePaths(QVariantMap &properties, const QgsPathResolver &pathResolver, bool saving)
Turns relative paths in properties map to absolute when reading and vice versa when writing.
QPointF offset() const
Returns the offset for the fill.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer's subsymbol. takes ownership of the passed symbol.
QgsRasterFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
bool applyBrushTransformFromContext(QgsSymbolRenderContext *context=nullptr) const override
Returns true if the image brush should be transformed using the render context's texture origin.
void setCoordinateMode(Qgis::SymbolCoordinateReference mode)
Set the coordinate mode for fill.
A rectangle specified with double values.
Contains information about the context of a rendering operation.
double scaleFactor() const
Returns the scaling factor for the render to convert painter units to physical sizes.
void setScaleFactor(double factor)
Sets the scaling factor for the render to convert painter units to physical sizes.
QSet< QString > disabledSymbolLayersV2() const
When rendering a map layer in a second pass (for selective masking), some symbol layers may be disabl...
double convertToPainterUnits(double size, Qgis::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale(), Qgis::RenderSubcomponentProperty property=Qgis::RenderSubcomponentProperty::Generic) const
Converts a size from the specified units to painter units (pixels).
QPainter * painter()
Returns the destination QPainter for the render operation.
double rendererScale() const
Returns the renderer map scale.
void setPainterFlagsUsingContext(QPainter *painter=nullptr) const
Sets relevant flags on a destination painter, using the flags and settings currently defined for the ...
QgsExpressionContext & expressionContext()
Gets the expression context.
void setDisabledSymbolLayersV2(const QSet< QString > &symbolLayers)
When rendering a map layer in a second pass (for selective masking), some symbol layers may be disabl...
void setRasterizedRenderingPolicy(Qgis::RasterizedRenderingPolicy policy)
Sets the policy controlling when rasterisation of content during renders is permitted.
void setFlag(Qgis::RenderContextFlag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected).
const QgsMapToPixel & mapToPixel() const
Returns the context's map to pixel transform, which transforms between map coordinates and device coo...
QColor selectionColor() const
Returns the color to use when rendering selected features.
void setMapToPixel(const QgsMapToPixel &mtp)
Sets the context's map to pixel transform, which transforms between map coordinates and device coordi...
QgsFeedback * feedback() const
Returns the feedback object that can be queried regularly during rendering to check if rendering shou...
QPointF textureOrigin() const
Returns the texture origin, which should be used as a brush transform when rendering using QBrush obj...
void setPainter(QPainter *p)
Sets the destination QPainter for the render operation.
bool renderingStopped() const
Returns true if the rendering operation has been stopped and any ongoing rendering should be canceled...
static QgsRenderContext fromQPainter(QPainter *painter)
Creates a default render context given a pixel based QPainter destination.
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
void setRendererScale(double scale)
Sets the renderer map scale.
Qgis::RenderContextFlags flags() const
Returns combination of flags used for rendering.
const QgsPathResolver & pathResolver() const
Returns the path resolver for conversion between relative and absolute paths during rendering operati...
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
void setParameters(const QMap< QString, QgsProperty > ¶meters)
Sets the dynamic SVG parameters.
QString svgFilePath() const
Returns the path to the SVG file used to render the fill.
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
QColor dxfColor(QgsSymbolRenderContext &context) const override
Gets color.
static QgsSymbolLayer * createFromSld(QDomElement &element)
Creates a new QgsSVGFillSymbolLayer from a SLD element.
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer's subsymbol. takes ownership of the passed symbol.
QColor svgStrokeColor() const
Returns the stroke color used for rendering the SVG content.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
Qgis::RenderUnit patternWidthUnit() const
Returns the units for the width of the SVG images in the pattern.
const QgsMapUnitScale & svgStrokeWidthMapUnitScale() const
Returns the map unit scale for the pattern's stroke.
double svgStrokeWidth() const
Returns the stroke width used for rendering the SVG content.
QString layerType() const override
Returns a string that represents this layer type.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QMap< QString, QgsProperty > parameters() const
Returns the dynamic SVG parameters.
QgsSVGFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
QgsSVGFillSymbolLayer(const QString &svgFilePath, double width=20, double rotation=0.0)
Constructor for QgsSVGFillSymbolLayer, using the SVG picture at the specified absolute file path.
void setSvgFilePath(const QString &svgPath)
Sets the path to the SVG file to render in the fill.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsSVGFillSymbolLayer from a properties map.
QColor svgFillColor() const
Returns the fill color used for rendering the SVG content.
static void resolvePaths(QVariantMap &properties, const QgsPathResolver &pathResolver, bool saving)
Turns relative paths in properties map to absolute when reading and vice versa when writing.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
const QgsMapUnitScale & patternWidthMapUnitScale() const
Returns the map unit scale for the pattern's width.
Qgis::RenderUnit svgStrokeWidthUnit() const
Returns the units for the stroke width.
double patternWidth() const
Returns the width of the rendered SVG content within the fill (i.e.
bool hasDataDefinedProperties() const override
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
~QgsSVGFillSymbolLayer() override
void setMapUnitScale(const QgsMapUnitScale &scale) override
Q_DECL_DEPRECATED void toSld(QDomDocument &doc, QDomElement &element, const QVariantMap &props) const override
Saves the symbol layer as SLD.
void applyDataDefinedSettings(QgsSymbolRenderContext &context) override
Applies data defined settings prior to generating the fill symbol brush.
QgsMapUnitScale mapUnitScale() const override
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
QgsSymbol * subSymbol() override
Returns the symbol's sub symbol, if present.
Scoped object for saving and restoring a QPainter object's state.
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
QgsShapeburstFillSymbolLayer(const QColor &color=DEFAULT_SIMPLEFILL_COLOR, const QColor &color2=Qt::white, Qgis::GradientColorSource colorType=Qgis::GradientColorSource::SimpleTwoColor, int blurRadius=0, bool useWholeShape=true, double maxDistance=5)
Constructor for QgsShapeburstFillSymbolLayer.
QgsShapeburstFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
~QgsShapeburstFillSymbolLayer() override
int blurRadius() const
Returns the blur radius, which controls the amount of blurring applied to the fill.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
QColor color2() const
Returns the color used for the endpoint of the shapeburst fill.
void setMapUnitScale(const QgsMapUnitScale &scale) override
QgsMapUnitScale mapUnitScale() const override
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
bool canCauseArtifactsBetweenAdjacentTiles() const override
Returns true if the symbol layer rendering can cause visible artifacts across a single feature when t...
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsShapeburstFillSymbolLayer using the specified properties map containing symbol prope...
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
QPointF offset() const
Returns the offset for the shapeburst fill.
bool useWholeShape() const
Returns whether the shapeburst fill is set to cover the entire shape.
bool ignoreRings() const
Returns whether the shapeburst fill is set to ignore polygon interior rings.
double maxDistance() const
Returns the maximum distance from the shape's boundary which is shaded.
Qgis::SymbolLayerFlags flags() const override
Returns flags which control the symbol layer's behavior.
QString layerType() const override
Returns a string that represents this layer type.
Qgis::GradientColorSource colorType() const
Returns the color mode used for the shapeburst fill.
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
void setColorRamp(QgsColorRamp *ramp)
Sets the color ramp used to draw the shapeburst fill.
QgsSimpleFillSymbolLayer(const QColor &color=DEFAULT_SIMPLEFILL_COLOR, Qt::BrushStyle style=DEFAULT_SIMPLEFILL_STYLE, const QColor &strokeColor=DEFAULT_SIMPLEFILL_BORDERCOLOR, Qt::PenStyle strokeStyle=DEFAULT_SIMPLEFILL_BORDERSTYLE, double strokeWidth=DEFAULT_SIMPLEFILL_BORDERWIDTH, Qt::PenJoinStyle penJoinStyle=DEFAULT_SIMPLEFILL_JOINSTYLE)
double dxfWidth(const QgsDxfExport &e, QgsSymbolRenderContext &context) const override
Gets line width.
Qt::PenJoinStyle penJoinStyle() const
QColor strokeColor() const override
Returns the stroke color for the symbol layer.
QColor dxfBrushColor(QgsSymbolRenderContext &context) const override
Gets brush/fill color.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
Qt::BrushStyle dxfBrushStyle() const override
Gets brush/fill style.
QString ogrFeatureStyle(double mmScaleFactor, double mapUnitScaleFactor) const override
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
Qgis::SymbolLayerFlags flags() const override
Returns flags which control the symbol layer's behavior.
Qgis::RenderUnit mOffsetUnit
~QgsSimpleFillSymbolLayer() override
Q_DECL_DEPRECATED void toSld(QDomDocument &doc, QDomElement &element, const QVariantMap &props) const override
Saves the symbol layer as SLD.
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
QColor dxfColor(QgsSymbolRenderContext &context) const override
Gets color.
QColor fillColor() const override
Returns the fill color for the symbol layer.
Qt::PenStyle strokeStyle() const
QString layerType() const override
Returns a string that represents this layer type.
double dxfAngle(QgsSymbolRenderContext &context) const override
Gets angle.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QgsMapUnitScale mOffsetMapUnitScale
double strokeWidth() const
Qgis::RenderUnit mStrokeWidthUnit
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
QPointF offset() const
Returns the offset by which polygons will be translated during rendering.
Qt::PenStyle dxfPenStyle() const override
Gets pen style.
QgsMapUnitScale mStrokeWidthMapUnitScale
QImage toTiledPatternImage() const override
Renders the symbol layer as an image that can be used as a seamless pattern fill for polygons,...
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
QgsSimpleFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
Qt::PenStyle mStrokeStyle
QgsMapUnitScale mapUnitScale() const override
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
Qt::PenJoinStyle mPenJoinStyle
Qt::BrushStyle mBrushStyle
void setMapUnitScale(const QgsMapUnitScale &scale) override
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsSimpleFillSymbolLayer using the specified properties map containing symbol propertie...
static QgsSymbolLayer * createFromSld(QDomElement &element)
Holds SLD export options and other information related to SLD export of a QGIS layer style.
QString exportFilePath() const
Returns the export file path for the SLD.
void setExtraProperties(const QVariantMap &properties)
Sets the open ended set of properties that can drive/inform the SLD encoding.
void pushWarning(const QString &warning)
Pushes a warning message generated during the conversion.
Qgis::SldExportOptions exportOptions() const
Returns the export options.
QVariantMap extraProperties() const
Returns the open ended set of properties that can drive/inform the SLD encoding.
QByteArray getImageData(const QString &path, bool blocking=false) const
Gets the SVG content corresponding to the given path.
QPicture svgAsPicture(const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth, double widthScaleFactor, bool forceVectorOutput=false, double fixedAspectRatio=0, bool blocking=false, const QMap< QString, QString > ¶meters=QMap< QString, QString >())
Returns an SVG drawing as a QPicture.
void containsParams(const QString &path, bool &hasFillParam, QColor &defaultFillColor, bool &hasStrokeParam, QColor &defaultStrokeColor, bool &hasStrokeWidthParam, double &defaultStrokeWidth, bool blocking=false) const
Tests if an SVG file contains parameters for fill, stroke color, stroke width.
QImage svgAsImage(const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth, double widthScaleFactor, bool &fitsInCache, double fixedAspectRatio=0, bool blocking=false, const QMap< QString, QString > ¶meters=QMap< QString, QString >())
Returns an SVG drawing as a QImage.
static bool rotationFromSldElement(QDomElement &element, QString &rotationFunc)
static Qgis::MarkerClipMode decodeMarkerClipMode(const QString &string, bool *ok=nullptr)
Decodes a string representing a marker clip mode.
static QString encodePenStyle(Qt::PenStyle style)
static Qt::PenJoinStyle decodePenJoinStyle(const QString &str)
static QString encodeMapUnitScale(const QgsMapUnitScale &mapUnitScale)
static QgsStringMap evaluatePropertiesMap(const QMap< QString, QgsProperty > &propertiesMap, const QgsExpressionContext &context)
Evaluates a map of properties using the given context and returns a variant map with evaluated expres...
static bool displacementFromSldElement(QDomElement &element, QPointF &offset)
static QPointF polygonCentroid(const QPolygonF &points)
Calculate the centroid point of a QPolygonF.
static QString encodeBrushStyle(Qt::BrushStyle style)
static QString svgSymbolPathToName(const QString &path, const QgsPathResolver &pathResolver)
Determines an SVG symbol's name from its path.
static void externalGraphicToSld(QDomDocument &doc, QDomElement &element, const QString &path, const QString &mime, const QColor &color, double size=-1)
static QPointF polygonPointOnSurface(const QPolygonF &points, const QVector< QPolygonF > *rings=nullptr)
Calculate a point on the surface of a QPolygonF.
static QPointF toPoint(const QVariant &value, bool *ok=nullptr)
Converts a value to a point.
static void multiplyImageOpacity(QImage *image, qreal opacity)
Multiplies opacity of image pixel values with a (global) transparency value.
static QgsMapUnitScale decodeMapUnitScale(const QString &str)
static double rescaleUom(double size, Qgis::RenderUnit unit, const QVariantMap &props)
Rescales the given size based on the uomScale found in the props, if any is found,...
static std::unique_ptr< QgsSymbolLayer > createMarkerLayerFromSld(QDomElement &element)
Creates a new marker layer from a SLD DOM element.
static QString ogrFeatureStylePen(double width, double mmScaleFactor, double mapUnitsScaleFactor, const QColor &c, Qt::PenJoinStyle joinStyle=Qt::MiterJoin, Qt::PenCapStyle capStyle=Qt::FlatCap, double offset=0.0, const QVector< qreal > *dashPattern=nullptr)
Create ogr feature style string for pen.
static bool externalGraphicFromSld(QDomElement &element, QString &path, QString &mime, QColor &color, double &size)
static Q_DECL_DEPRECATED void parametricSvgToSld(QDomDocument &doc, QDomElement &graphicElem, const QString &path, const QColor &fillColor, double size, const QColor &strokeColor, double strokeWidth)
Encodes a reference to a parametric SVG into SLD, as a succession of parametric SVG using URL paramet...
static bool lineFromSld(QDomElement &element, Qt::PenStyle &penStyle, QColor &color, double &width, Qt::PenJoinStyle *penJoinStyle=nullptr, Qt::PenCapStyle *penCapStyle=nullptr, QVector< qreal > *customDashPattern=nullptr, double *dashOffset=nullptr)
static std::unique_ptr< QgsSymbolLayer > createLineLayerFromSld(QDomElement &element)
Creates a new line layer from a SLD DOM element.
static QString ogrFeatureStyleBrush(const QColor &fillColr)
Create ogr feature style string for brush.
static QString encodeLineClipMode(Qgis::LineClipMode mode)
Encodes a line clip mode to a string.
static Qgis::LineClipMode decodeLineClipMode(const QString &string, bool *ok=nullptr)
Decodes a string representing a line clip mode.
static QPointF pointOnLineWithDistance(QPointF startPoint, QPointF directionPoint, double distance)
Returns a point on the line from startPoint to directionPoint that is a certain distance away from th...
static QSize tileSize(int width, int height, double &angleRad)
Calculate the minimum size in pixels of a symbol tile given the symbol width and height and the symbo...
static Qt::BrushStyle decodeBrushStyle(const QString &str)
static QDomElement createVendorOptionElement(QDomDocument &doc, const QString &name, const QString &value)
static bool wellKnownMarkerFromSld(QDomElement &element, QString &name, QColor &color, QColor &strokeColor, Qt::PenStyle &strokeStyle, double &strokeWidth, double &size)
Extracts properties from an SLD marker definition.
static void createDisplacementElement(QDomDocument &doc, QDomElement &element, QPointF offset)
static QString svgSymbolNameToPath(const QString &name, const QgsPathResolver &pathResolver)
Determines an SVG symbol's path from its name.
static QString encodeColor(const QColor &color)
static bool fillFromSld(QDomElement &element, Qt::BrushStyle &brushStyle, QColor &color)
static Q_DECL_DEPRECATED void fillToSld(QDomDocument &doc, QDomElement &element, Qt::BrushStyle brushStyle, const QColor &color=QColor())
Exports fill details to an SLD element.
static Qgis::RenderUnit decodeSldUom(const QString &str, double *scaleFactor=nullptr)
Decodes a SLD unit of measure string to a render unit.
static Q_DECL_DEPRECATED void createGeometryElement(QDomDocument &doc, QDomElement &element, const QString &geomFunc)
Creates an SLD geometry element.
static double estimateMaxSymbolBleed(QgsSymbol *symbol, const QgsRenderContext &context)
Returns the maximum estimated bleed for the symbol.
static Q_DECL_DEPRECATED void wellKnownMarkerToSld(QDomDocument &doc, QDomElement &element, const QString &name, const QColor &color, const QColor &strokeColor, Qt::PenStyle strokeStyle, double strokeWidth=-1, double size=-1)
Exports a marker to SLD.
static Qt::PenStyle decodePenStyle(const QString &str)
static Q_DECL_DEPRECATED void createRotationElement(QDomDocument &doc, QDomElement &element, const QString &rotationFunc)
Creates SLD rotation element.
static Qgis::SymbolCoordinateReference decodeCoordinateReference(const QString &string, bool *ok=nullptr)
Decodes a string representing a symbol coordinate reference mode.
static QString encodePoint(QPointF point)
Encodes a QPointF to a string.
static QString encodePenJoinStyle(Qt::PenJoinStyle style)
static QgsStringMap getVendorOptionList(QDomElement &element)
static QPointF decodePoint(const QString &string)
Decodes a QSizeF from a string.
static QString encodeCoordinateReference(Qgis::SymbolCoordinateReference coordinateReference)
Encodes a symbol coordinate reference mode to a string.
static QString encodeMarkerClipMode(Qgis::MarkerClipMode mode)
Encodes a marker clip mode to a string.
static void lineToSld(QDomDocument &doc, QDomElement &element, Qt::PenStyle penStyle, const QColor &color, QgsSldExportContext &context, double width=-1, const Qt::PenJoinStyle *penJoinStyle=nullptr, const Qt::PenCapStyle *penCapStyle=nullptr, const QVector< qreal > *customDashPattern=nullptr, double dashOffset=0.0)
virtual bool setSubSymbol(QgsSymbol *symbol)
Sets layer's subsymbol. takes ownership of the passed symbol.
bool shouldRenderUsingSelectionColor(const QgsSymbolRenderContext &context) const
Returns true if the symbol layer should be rendered using the selection color from the render context...
Qgis::SymbolType type() const
virtual QColor fillColor() const
Returns the fill color for the symbol layer.
static const bool SELECTION_IS_OPAQUE
Whether styles for selected features ignore symbol alpha.
bool installMasks(QgsRenderContext &context, bool recursive, const QRectF &rect=QRectF())
When rendering, install masks on context painter.
void removeMasks(QgsRenderContext &context, bool recursive)
When rendering, remove previously installed masks from context painter if recursive is true masks are...
virtual QSet< QString > usedAttributes(const QgsRenderContext &context) const
Returns the set of attributes referenced by the layer.
void copyDataDefinedProperties(QgsSymbolLayer *destLayer) const
Copies all data defined properties of this layer to another symbol layer.
@ GradientType
Gradient fill type.
@ SecondaryColor
Secondary color (eg for gradient fills).
@ File
Filename, eg for svg files.
@ GradientReference2Y
Gradient reference point 2 y.
@ GradientReference1X
Gradient reference point 1 x.
@ OffsetY
Vertical offset.
@ OffsetX
Horizontal offset.
@ GradientReference1Y
Gradient reference point 1 y.
@ GradientSpread
Gradient spread mode.
@ ShapeburstMaxDistance
Shapeburst fill from edge distance.
@ StrokeStyle
Stroke style (eg solid, dashed).
@ DistanceY
Vertical distance between points.
@ DensityArea
Density area.
@ ClipPoints
Whether markers should be clipped to polygon boundaries.
@ LineClipping
Line clipping mode.
@ ShapeburstIgnoreRings
Shapeburst ignore rings.
@ ShapeburstUseWholeShape
Shapeburst use whole shape.
@ DisplacementX
Horizontal displacement.
@ CoordinateMode
Gradient coordinate mode.
@ FillStyle
Fill style (eg solid, dots).
@ GradientReference2X
Gradient reference point 2 x.
@ StrokeColor
Stroke color.
@ BlurRadius
Shapeburst blur radius.
@ MarkerClipping
Marker clipping mode.
@ RandomSeed
Random number seed.
@ LineAngle
Line angle, or angle of hash lines for hash line symbols.
@ JoinStyle
Line join style.
@ RandomOffsetY
Random offset Y.
@ DisplacementY
Vertical displacement.
@ DistanceX
Horizontal distance between points.
@ GradientReference1IsCentroid
Gradient reference point 1 is centroid.
@ StrokeWidth
Stroke width.
@ GradientReference2IsCentroid
Gradient reference point 2 is centroid.
@ LineDistance
Distance between lines, or length of lines for hash line symbols.
@ RandomOffsetX
Random offset X.
void restoreOldDataDefinedProperties(const QVariantMap &stringMap)
Restores older data defined properties from string map.
virtual double estimateMaxBleed(const QgsRenderContext &context) const
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
static const bool SELECT_FILL_BORDER
Whether fill styles for selected features also highlight symbol stroke.
virtual bool rendersIdenticallyTo(const QgsSymbolLayer *other) const
Returns true if this symbol layer will always render identically to an other symbol layer.
virtual QString layerType() const =0
Returns a string that represents this layer type.
virtual QColor color() const
Returns the "representative" color of the symbol layer.
virtual QColor strokeColor() const
Returns the stroke color for the symbol layer.
void copyPaintEffect(QgsSymbolLayer *destLayer) const
Copies paint effect of this layer to another symbol layer.
virtual Qgis::SymbolLayerFlags flags() const
Returns flags which control the symbol layer's behavior.
QgsPropertyCollection mDataDefinedProperties
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the symbol layer's property collection, used for data defined overrides.
static const bool SELECT_FILL_STYLE
Whether fill styles for selected features uses symbol layer style.
virtual bool hasDataDefinedProperties() const
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
QgsSymbolLayer(const QgsSymbolLayer &other)
Encapsulates the context in which a symbol is being rendered.
const QgsFeature * feature() const
Returns the current feature being rendered.
QgsFields fields() const
Fields of the layer.
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for data defined symbology.
bool forceVectorRendering() const
Returns true if symbol must be rendered using vector methods, and optimisations like pre-rendered ima...
qreal opacity() const
Returns the opacity for the symbol.
QgsRenderContext & renderContext()
Returns a reference to the context's render context.
Abstract base class for all rendered symbols.
QColor color() const
Returns the symbol's color.
Qgis::SymbolType type() const
Returns the symbol's type.
double interval() const
Returns the interval between individual symbols.
const QgsMapUnitScale & intervalMapUnitScale() const
Returns the map unit scale for the interval between symbols.
void setInterval(double interval)
Sets the interval between individual symbols.
Qgis::RenderUnit intervalUnit() const
Returns the units for the interval between symbols.
static Q_INVOKABLE Qgis::RenderUnit decodeRenderUnit(const QString &string, bool *ok=nullptr)
Decodes a render unit from a string.
static Q_INVOKABLE QString encodeUnit(Qgis::DistanceUnit unit)
Encodes a distance unit to a string.
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference).
QMap< QString, QString > QgsStringMap
T qgsgeometry_cast(QgsAbstractGeometry *geom)
#define DEFAULT_SIMPLEFILL_JOINSTYLE
#define DEFAULT_SIMPLEFILL_COLOR
#define DEFAULT_SIMPLEFILL_STYLE
#define DEFAULT_SIMPLEFILL_BORDERSTYLE
#define DEFAULT_SIMPLEFILL_BORDERCOLOR
#define DEFAULT_SIMPLEFILL_BORDERWIDTH
#define QgsDebugError(str)
QList< QgsSymbolLayer * > QgsSymbolLayerList
Single variable definition for use within a QgsExpressionContextScope.