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