44#include <QPagedPaintDevice> 
   46#include <QSvgRenderer> 
   47#include <QDomDocument> 
   54    Qt::PenJoinStyle penJoinStyle )
 
   55  : mBrushStyle( style )
 
   56  , mStrokeColor( strokeColor )
 
   57  , mStrokeStyle( strokeStyle )
 
   58  , mStrokeWidth( strokeWidth )
 
   59  , mPenJoinStyle( penJoinStyle )
 
 
  103void QgsSimpleFillSymbolLayer::applyDataDefinedSymbology( 
QgsSymbolRenderContext &context, QBrush &brush, QPen &pen, QPen &selPen )
 
  128    penColor.setAlphaF( context.
opacity() * penColor.alphaF() );
 
  129    pen.setColor( penColor );
 
  137      double width = exprVal.toDouble( &ok );
 
  141        pen.setWidthF( width );
 
  142        selPen.setWidthF( width );
 
  179  if ( props.contains( QStringLiteral( 
"color" ) ) )
 
  181  if ( props.contains( QStringLiteral( 
"style" ) ) )
 
  183  if ( props.contains( QStringLiteral( 
"color_border" ) ) )
 
  188  else if ( props.contains( QStringLiteral( 
"outline_color" ) ) )
 
  192  else if ( props.contains( QStringLiteral( 
"line_color" ) ) )
 
  197  if ( props.contains( QStringLiteral( 
"style_border" ) ) )
 
  202  else if ( props.contains( QStringLiteral( 
"outline_style" ) ) )
 
  206  else if ( props.contains( QStringLiteral( 
"line_style" ) ) )
 
  210  if ( props.contains( QStringLiteral( 
"width_border" ) ) )
 
  213    strokeWidth = props[QStringLiteral( 
"width_border" )].toDouble();
 
  215  else if ( props.contains( QStringLiteral( 
"outline_width" ) ) )
 
  217    strokeWidth = props[QStringLiteral( 
"outline_width" )].toDouble();
 
  219  else if ( props.contains( QStringLiteral( 
"line_width" ) ) )
 
  221    strokeWidth = props[QStringLiteral( 
"line_width" )].toDouble();
 
  223  if ( props.contains( QStringLiteral( 
"offset" ) ) )
 
  225  if ( props.contains( QStringLiteral( 
"joinstyle" ) ) )
 
  230  if ( props.contains( QStringLiteral( 
"border_width_unit" ) ) )
 
  234  else if ( props.contains( QStringLiteral( 
"outline_width_unit" ) ) )
 
  238  else if ( props.contains( QStringLiteral( 
"line_width_unit" ) ) )
 
  242  if ( props.contains( QStringLiteral( 
"offset_unit" ) ) )
 
  245  if ( props.contains( QStringLiteral( 
"border_width_map_unit_scale" ) ) )
 
  247  if ( props.contains( QStringLiteral( 
"offset_map_unit_scale" ) ) )
 
  250  sl->restoreOldDataDefinedProperties( props );
 
 
  258  return QStringLiteral( 
"SimpleFill" );
 
 
  270    selColor.setAlphaF( context.
opacity() );
 
 
  329  if ( 
mBrush.style() == Qt::SolidPattern || 
mBrush.style() == Qt::NoBrush || !
dynamic_cast<QPagedPaintDevice *
>( p->device() ) )
 
  341    p->setPen( Qt::NoPen );
 
  345    p->setBrush( Qt::NoBrush );
 
 
  362  map[QStringLiteral( 
"outline_width" )] = QString::number( 
mStrokeWidth );
 
 
  390  QDomElement symbolizerElem = doc.createElement( QStringLiteral( 
"se:PolygonSymbolizer" ) );
 
  391  if ( !props.value( QStringLiteral( 
"uom" ), QString() ).toString().isEmpty() )
 
  392    symbolizerElem.setAttribute( QStringLiteral( 
"uom" ), props.value( QStringLiteral( 
"uom" ), QString() ).toString() );
 
  393  element.appendChild( symbolizerElem );
 
  402  bool exportOk { 
false };
 
  406    if ( ! image.isNull() )
 
  409      QDomElement fillElem = doc.createElement( QStringLiteral( 
"se:Fill" ) );
 
  410      symbolizerElem.appendChild( fillElem );
 
  411      QDomElement graphicFillElem = doc.createElement( QStringLiteral( 
"se:GraphicFill" ) );
 
  412      fillElem.appendChild( graphicFillElem );
 
  413      QDomElement graphicElem = doc.createElement( QStringLiteral( 
"se:Graphic" ) );
 
  414      graphicFillElem.appendChild( graphicElem );
 
  416      const QFileInfo info { context.exportFilePath() };
 
  417      QString pngPath { info.completeSuffix().isEmpty() ? context.exportFilePath() : context.exportFilePath().chopped( info.completeSuffix().length() ).append( QStringLiteral( 
"png" ) ) };
 
  419      image.save( pngPath );
 
  434      const double alpha { props.value( QStringLiteral( 
"alpha" ), QVariant() ).toDouble( &ok ) };
 
  440      QDomElement fillElem = doc.createElement( QStringLiteral( 
"se:Fill" ) );
 
  441      symbolizerElem.appendChild( fillElem );
 
  448      QDomElement strokeElem = doc.createElement( QStringLiteral( 
"se:Stroke" ) );
 
  449      symbolizerElem.appendChild( strokeElem );
 
  453      const double alpha { props.value( QStringLiteral( 
"alpha" ), QVariant() ).toDouble( &ok ) };
 
 
  473  symbolStyle.append( 
';' );
 
 
  482  Qt::BrushStyle fillStyle;
 
  486  QDomElement fillElem = element.firstChildElement( QStringLiteral( 
"Fill" ) );
 
  489  QDomElement strokeElem = element.firstChildElement( QStringLiteral( 
"Stroke" ) );
 
  495  double scaleFactor = 1.0;
 
  496  const QString uom = element.attribute( QStringLiteral( 
"uom" ) );
 
  503  sl->setOutputUnit( sldUnitSize );
 
 
  512  return penBleed + offsetBleed;
 
 
  570  QPixmap pixmap( QSize( 32, 32 ) );
 
  571  pixmap.fill( Qt::transparent );
 
  573  painter.begin( &pixmap );
 
  574  painter.setRenderHint( QPainter::Antialiasing );
 
  582  std::unique_ptr< QgsSimpleFillSymbolLayer > layerClone( 
clone() );
 
  583  layerClone->setStrokeStyle( Qt::PenStyle::NoPen );
 
  584  layerClone->drawPreviewIcon( symbolContext, pixmap.size() );
 
  586  return pixmap.toImage();
 
 
  594  : mGradientColorType( colorType )
 
  595  , mGradientType( gradientType )
 
  596  , mCoordinateMode( coordinateMode )
 
  597  , mGradientSpread( spread )
 
  598  , mReferencePoint1( QPointF( 0.5, 0 ) )
 
  599  , mReferencePoint2( QPointF( 0.5, 1 ) )
 
 
  620  bool refPoint1IsCentroid = 
false;
 
  622  bool refPoint2IsCentroid = 
false;
 
  627  if ( props.contains( QStringLiteral( 
"type" ) ) )
 
  629  if ( props.contains( QStringLiteral( 
"coordinate_mode" ) ) )
 
  631  if ( props.contains( QStringLiteral( 
"spread" ) ) )
 
  633  if ( props.contains( QStringLiteral( 
"color_type" ) ) )
 
  635  if ( props.contains( QStringLiteral( 
"gradient_color" ) ) )
 
  640  else if ( props.contains( QStringLiteral( 
"color" ) ) )
 
  644  if ( props.contains( QStringLiteral( 
"gradient_color2" ) ) )
 
  649  if ( props.contains( QStringLiteral( 
"reference_point1" ) ) )
 
  651  if ( props.contains( QStringLiteral( 
"reference_point1_iscentroid" ) ) )
 
  652    refPoint1IsCentroid = props[QStringLiteral( 
"reference_point1_iscentroid" )].toInt();
 
  653  if ( props.contains( QStringLiteral( 
"reference_point2" ) ) )
 
  655  if ( props.contains( QStringLiteral( 
"reference_point2_iscentroid" ) ) )
 
  656    refPoint2IsCentroid = props[QStringLiteral( 
"reference_point2_iscentroid" )].toInt();
 
  657  if ( props.contains( QStringLiteral( 
"angle" ) ) )
 
  658    angle = props[QStringLiteral( 
"angle" )].toDouble();
 
  660  if ( props.contains( QStringLiteral( 
"offset" ) ) )
 
  677  if ( props.contains( QStringLiteral( 
"offset_unit" ) ) )
 
  679  if ( props.contains( QStringLiteral( 
"offset_map_unit_scale" ) ) )
 
  682  sl->setReferencePoint1IsCentroid( refPoint1IsCentroid );
 
  684  sl->setReferencePoint2IsCentroid( refPoint2IsCentroid );
 
  685  sl->setAngle( 
angle );
 
  687    sl->setColorRamp( gradientRamp );
 
  689  sl->restoreOldDataDefinedProperties( props );
 
 
  702  return QStringLiteral( 
"GradientFill" );
 
 
  705void QgsGradientFillSymbolLayer::applyDataDefinedSymbology( 
QgsSymbolRenderContext &context, 
const QPolygonF &points )
 
  750      if ( currentType == QObject::tr( 
"linear" ) )
 
  754      else if ( currentType == QObject::tr( 
"radial" ) )
 
  758      else if ( currentType == QObject::tr( 
"conical" ) )
 
  772      if ( currentCoordMode == QObject::tr( 
"feature" ) )
 
  776      else if ( currentCoordMode == QObject::tr( 
"viewport" ) )
 
  790      if ( currentSpread == QObject::tr( 
"pad" ) )
 
  794      else if ( currentSpread == QObject::tr( 
"repeat" ) )
 
  798      else if ( currentSpread == QObject::tr( 
"reflect" ) )
 
  845  if ( refPoint1IsCentroid || refPoint2IsCentroid )
 
  850    QRectF bbox = points.boundingRect();
 
  851    double centroidX = ( centroid.
x() - bbox.left() ) / bbox.width();
 
  852    double centroidY = ( centroid.
y() - bbox.top() ) / bbox.height();
 
  854    if ( refPoint1IsCentroid )
 
  856      refPoint1X = centroidX;
 
  857      refPoint1Y = centroidY;
 
  859    if ( refPoint2IsCentroid )
 
  861      refPoint2X = centroidX;
 
  862      refPoint2Y = centroidY;
 
  868                 spread, QPointF( refPoint1X, refPoint1Y ), QPointF( refPoint2X, refPoint2Y ), 
angle );
 
  871QPointF QgsGradientFillSymbolLayer::rotateReferencePoint( QPointF refPoint, 
double angle )
 
  876  QLineF refLine = QLineF( QPointF( 0.5, 0.5 ), refPoint );
 
  878  refLine.setAngle( refLine.angle() + 
angle );
 
  880  QPointF rotatedReferencePoint = refLine.p2();
 
  882  if ( rotatedReferencePoint.x() > 1 )
 
  883    rotatedReferencePoint.setX( 1 );
 
  884  if ( rotatedReferencePoint.x() < 0 )
 
  885    rotatedReferencePoint.setX( 0 );
 
  886  if ( rotatedReferencePoint.y() > 1 )
 
  887    rotatedReferencePoint.setY( 1 );
 
  888  if ( rotatedReferencePoint.y() < 0 )
 
  889    rotatedReferencePoint.setY( 0 );
 
  891  return rotatedReferencePoint;
 
  898    QPointF referencePoint1, QPointF referencePoint2, 
const double angle )
 
  903  QColor fillColor2 = 
color2;
 
  904  fillColor2.setAlphaF( context.
opacity() * fillColor2.alphaF() );
 
  915      gradient = QLinearGradient( rotatedReferencePoint1, rotatedReferencePoint2 );
 
  918      gradient = QRadialGradient( rotatedReferencePoint1, QLineF( rotatedReferencePoint1, rotatedReferencePoint2 ).length() );
 
  921      gradient = QConicalGradient( rotatedReferencePoint1, QLineF( rotatedReferencePoint1, rotatedReferencePoint2 ).
angle() );
 
  927      gradient.setCoordinateMode( QGradient::ObjectBoundingMode );
 
  930      gradient.setCoordinateMode( QGradient::StretchToDeviceMode );
 
  936      gradient.setSpread( QGradient::PadSpread );
 
  939      gradient.setSpread( QGradient::ReflectSpread );
 
  942      gradient.setSpread( QGradient::RepeatSpread );
 
  958    gradient.setColorAt( 1.0, fillColor2 );
 
  962  brush = QBrush( gradient );
 
  969    selColor.setAlphaF( context.
opacity() );
 
 
  986  applyDataDefinedSymbology( context, points );
 
  990  p->setPen( Qt::NoPen );
 
 
 1023  map[QStringLiteral( 
"color_type" )] = QString::number( 
static_cast< int >( 
mGradientColorType ) );
 
 1024  map[QStringLiteral( 
"type" )] = QString::number( 
static_cast<int>( 
mGradientType ) );
 
 1025  map[QStringLiteral( 
"coordinate_mode" )] = QString::number( 
static_cast< int >( 
mCoordinateMode ) );
 
 1026  map[QStringLiteral( 
"spread" )] = QString::number( 
static_cast< int >( 
mGradientSpread ) );
 
 1031  map[QStringLiteral( 
"angle" )] = QString::number( 
mAngle );
 
 
 1057  return sl.release();
 
 
 1099    int blurRadius, 
bool useWholeShape, 
double maxDistance )
 
 1100  : mBlurRadius( blurRadius )
 
 1101  , mUseWholeShape( useWholeShape )
 
 1102  , mMaxDistance( maxDistance )
 
 1103  , mColorType( colorType )
 
 
 1122  if ( props.contains( QStringLiteral( 
"color_type" ) ) )
 
 1126  if ( props.contains( QStringLiteral( 
"shapeburst_color" ) ) )
 
 1131  else if ( props.contains( QStringLiteral( 
"color" ) ) )
 
 1136  if ( props.contains( QStringLiteral( 
"shapeburst_color2" ) ) )
 
 1141  else if ( props.contains( QStringLiteral( 
"gradient_color2" ) ) )
 
 1145  if ( props.contains( QStringLiteral( 
"blur_radius" ) ) )
 
 1147    blurRadius = props[QStringLiteral( 
"blur_radius" )].toInt();
 
 1149  if ( props.contains( QStringLiteral( 
"use_whole_shape" ) ) )
 
 1151    useWholeShape = props[QStringLiteral( 
"use_whole_shape" )].toInt();
 
 1153  if ( props.contains( QStringLiteral( 
"max_distance" ) ) )
 
 1155    maxDistance = props[QStringLiteral( 
"max_distance" )].toDouble();
 
 1157  if ( props.contains( QStringLiteral( 
"offset" ) ) )
 
 1176  if ( props.contains( QStringLiteral( 
"offset_unit" ) ) )
 
 1180  if ( props.contains( QStringLiteral( 
"distance_unit" ) ) )
 
 1184  if ( props.contains( QStringLiteral( 
"offset_map_unit_scale" ) ) )
 
 1188  if ( props.contains( QStringLiteral( 
"distance_map_unit_scale" ) ) )
 
 1192  if ( props.contains( QStringLiteral( 
"ignore_rings" ) ) )
 
 1194    sl->setIgnoreRings( props[QStringLiteral( 
"ignore_rings" )].toInt() );
 
 1198    sl->setColorRamp( gradientRamp );
 
 1201  sl->restoreOldDataDefinedProperties( props );
 
 1203  return sl.release();
 
 
 1208  return QStringLiteral( 
"ShapeburstFill" );
 
 
 1213  if ( mGradientRamp.get() == ramp )
 
 1216  mGradientRamp.reset( ramp );
 
 
 1219void QgsShapeburstFillSymbolLayer::applyDataDefinedSymbology( 
QgsSymbolRenderContext &context, QColor &color, QColor &color2, 
int &blurRadius, 
bool &useWholeShape,
 
 1220    double &maxDistance, 
bool &ignoreRings )
 
 1277    selColor.setAlphaF( context.
opacity() );
 
 1278  mSelBrush = QBrush( selColor );
 
 
 1295  if ( useSelectedColor )
 
 1298    p->setBrush( mSelBrush );
 
 1299    QPointF 
offset = mOffset;
 
 1334  int outputPixelMaxDist = 0;
 
 1342  std::unique_ptr< QgsGradientColorRamp > twoColorGradientRamp;
 
 1345    twoColorGradientRamp = std::make_unique< QgsGradientColorRamp >( color1, 
color2 );
 
 1349  p->setPen( QPen( Qt::NoPen ) );
 
 1354  int pointsWidth = 
static_cast< int >( std::round( points.boundingRect().width() ) );
 
 1355  int pointsHeight = 
static_cast< int >( std::round( points.boundingRect().height() ) );
 
 1356  int imWidth = pointsWidth + ( sideBuffer * 2 );
 
 1357  int imHeight = pointsHeight + ( sideBuffer * 2 );
 
 1363  std::unique_ptr< QImage > fillImage = std::make_unique< QImage >( imWidth,
 
 1364                                        imHeight, QImage::Format_ARGB32_Premultiplied );
 
 1365  if ( fillImage->isNull() )
 
 1375  std::unique_ptr< QImage > alphaImage = std::make_unique< QImage >( fillImage->width(), fillImage->height(), QImage::Format_ARGB32_Premultiplied );
 
 1376  if ( alphaImage->isNull() )
 
 1388  fillImage->fill( Qt::black );
 
 1394  alphaImage->fill( Qt::transparent );
 
 1400  QPainter imgPainter;
 
 1401  imgPainter.begin( alphaImage.get() );
 
 1402  imgPainter.setRenderHint( QPainter::Antialiasing, 
true );
 
 1403  imgPainter.setBrush( QBrush( Qt::white ) );
 
 1404  imgPainter.setPen( QPen( Qt::black ) );
 
 1405  imgPainter.translate( -points.boundingRect().left() + sideBuffer, - points.boundingRect().top() + sideBuffer );
 
 1414  imgPainter.begin( fillImage.get() );
 
 1417    imgPainter.drawImage( 0, 0, *alphaImage );
 
 1424    imgPainter.setBrush( QBrush( Qt::white ) );
 
 1425    imgPainter.setPen( QPen( Qt::black ) );
 
 1426    imgPainter.translate( -points.boundingRect().left() + sideBuffer, - points.boundingRect().top() + sideBuffer );
 
 1435  double *dtArray = distanceTransform( fillImage.get(), context.
renderContext() );
 
 1455  imgPainter.begin( fillImage.get() );
 
 1456  imgPainter.setCompositionMode( QPainter::CompositionMode_DestinationIn );
 
 1457  imgPainter.drawImage( 0, 0, *alphaImage );
 
 1465  QPointF 
offset = mOffset;
 
 1482  p->drawImage( points.boundingRect().left() - sideBuffer, points.boundingRect().top() - sideBuffer, *fillImage );
 
 
 1493void QgsShapeburstFillSymbolLayer::distanceTransform1d( 
double *f, 
int n, 
int *v, 
double *z, 
double *d )
 
 1499  for ( 
int q = 1; q <= n - 1; q++ )
 
 1501    double s  = ( ( f[q] + 
static_cast< double >( q ) * q ) - ( f[v[k]] + ( 
static_cast< double >( v[k] ) * v[k] ) ) ) / ( 2 * q - 2 * v[k] );
 
 1505      s  = ( ( f[q] + 
static_cast< double >( q ) * q ) - ( f[v[k]] + ( 
static_cast< double >( v[k] ) * v[k] ) ) ) / ( 2 * q - 2 * v[k] );
 
 1514  for ( 
int q = 0; q <= n - 1; q++ )
 
 1516    while ( z[k + 1] < q )
 
 1518    d[q] = 
static_cast< double >( q - v[k] ) * ( q - v[k] ) + f[v[k]];
 
 1523void QgsShapeburstFillSymbolLayer::distanceTransform2d( 
double *im, 
int width, 
int height, 
QgsRenderContext &context )
 
 1525  int maxDimension = std::max( width, height );
 
 1526  double *f = 
new double[ maxDimension ];
 
 1527  int *v = 
new int[ maxDimension ];
 
 1528  double *z = 
new double[ maxDimension + 1 ];
 
 1529  double *d = 
new double[ maxDimension ];
 
 1532  for ( 
int x = 0; x < width; x++ )
 
 1537    for ( 
int y = 0; y < height; y++ )
 
 1539      f[y] = im[ x + 
static_cast< std::size_t
>( y ) * width ];
 
 1541    distanceTransform1d( f, height, v, z, d );
 
 1542    for ( 
int y = 0; y < height; y++ )
 
 1544      im[ x + 
static_cast< std::size_t
>( y ) * width ] = d[y];
 
 1549  for ( 
int y = 0; y < height; y++ )
 
 1554    for ( 
int x = 0; x < width; x++ )
 
 1556      f[x] = im[  x + 
static_cast< std::size_t
>( y ) * width ];
 
 1558    distanceTransform1d( f, width, v, z, d );
 
 1559    for ( 
int x = 0; x < width; x++ )
 
 1561      im[  x + 
static_cast< std::size_t
>( y ) * width ] = d[x];
 
 1572double *QgsShapeburstFillSymbolLayer::distanceTransform( QImage *im, 
QgsRenderContext &context )
 
 1574  int width = im->width();
 
 1575  int height = im->height();
 
 1577  double *dtArray = 
new double[
static_cast< std::size_t
>( width ) * height];
 
 1581  std::size_t idx = 0;
 
 1582  for ( 
int heightIndex = 0; heightIndex < height; ++heightIndex )
 
 1587    const QRgb *scanLine = 
reinterpret_cast< const QRgb * 
>( im->constScanLine( heightIndex ) );
 
 1588    for ( 
int widthIndex = 0; widthIndex < width; ++widthIndex )
 
 1590      tmpRgb = scanLine[widthIndex];
 
 1591      if ( qRed( tmpRgb ) == 0 )
 
 1599        dtArray[ idx ] = 
INF;
 
 1606  distanceTransform2d( dtArray, width, height, context );
 
 1611void QgsShapeburstFillSymbolLayer::dtArrayToQImage( 
double *array, QImage *im, 
QgsColorRamp *ramp, 
QgsRenderContext &context, 
bool useWholeShape, 
int maxPixelDistance )
 
 1613  int width = im->width();
 
 1614  int height = im->height();
 
 1617  double maxDistanceValue;
 
 1622    double dtMaxValue = array[0];
 
 1623    for ( std::size_t i = 1; i < static_cast< std::size_t >( width ) * height; ++i )
 
 1625      if ( array[i] > dtMaxValue )
 
 1627        dtMaxValue = array[i];
 
 1632    maxDistanceValue = std::sqrt( dtMaxValue );
 
 1637    maxDistanceValue = maxPixelDistance;
 
 1641  std::size_t idx = 0;
 
 1642  double squaredVal = 0;
 
 1645  for ( 
int heightIndex = 0; heightIndex < height; ++heightIndex )
 
 1650    QRgb *scanLine = 
reinterpret_cast< QRgb * 
>( im->scanLine( heightIndex ) );
 
 1651    for ( 
int widthIndex = 0; widthIndex < width; ++widthIndex )
 
 1654      squaredVal = array[idx];
 
 1657      if ( maxDistanceValue > 0 )
 
 1659        pixVal = squaredVal > 0 ? std::min( ( std::sqrt( squaredVal ) / maxDistanceValue ), 1.0 ) : 0;
 
 1668      scanLine[widthIndex] = qPremultiply( ramp->
color( pixVal ).rgba() );
 
 1679  map[QStringLiteral( 
"color_type" )] = QString::number( 
static_cast< int >( mColorType ) );
 
 1680  map[QStringLiteral( 
"blur_radius" )] = QString::number( mBlurRadius );
 
 1681  map[QStringLiteral( 
"use_whole_shape" )] = QString::number( mUseWholeShape );
 
 1682  map[QStringLiteral( 
"max_distance" )] = QString::number( mMaxDistance );
 
 1685  map[QStringLiteral( 
"ignore_rings" )] = QString::number( mIgnoreRings );
 
 1689  if ( mGradientRamp )
 
 1691    map.insert( mGradientRamp->properties() );
 
 
 1699  std::unique_ptr< QgsShapeburstFillSymbolLayer > sl = std::make_unique< QgsShapeburstFillSymbolLayer >( 
mColor, mColor2, mColorType, mBlurRadius, mUseWholeShape, mMaxDistance );
 
 1700  if ( mGradientRamp )
 
 1702    sl->setColorRamp( mGradientRamp->clone() );
 
 1704  sl->setDistanceUnit( mDistanceUnit );
 
 1705  sl->setDistanceMapUnitScale( mDistanceMapUnitScale );
 
 1706  sl->setIgnoreRings( mIgnoreRings );
 
 1707  sl->setOffset( mOffset );
 
 1708  sl->setOffsetUnit( mOffsetUnit );
 
 1709  sl->setOffsetMapUnitScale( mOffsetMapUnitScale );
 
 1712  return sl.release();
 
 
 1717  double offsetBleed = context.
convertToPainterUnits( std::max( std::fabs( mOffset.x() ), std::fabs( mOffset.y() ) ), mOffsetUnit, mOffsetMapUnitScale );
 
 
 1728  mDistanceUnit = unit;
 
 
 1734  if ( mDistanceUnit == mOffsetUnit )
 
 1736    return mDistanceUnit;
 
 
 1749  mDistanceMapUnitScale = scale;
 
 1750  mOffsetMapUnitScale = scale;
 
 
 1755  if ( mDistanceMapUnitScale == mOffsetMapUnitScale )
 
 1757    return mDistanceMapUnitScale;
 
 
 1782  p->setPen( QPen( Qt::NoPen ) );
 
 1784  QTransform bkTransform = 
mBrush.transform();
 
 1788    QTransform t = 
mBrush.transform();
 
 1789    t.translate( leftCorner.x(), leftCorner.y() );
 
 1790    mBrush.setTransform( t );
 
 1794    QTransform t = 
mBrush.transform();
 
 1795    t.translate( 0, 0 );
 
 1796    mBrush.setTransform( t );
 
 1800  if ( useSelectedColor )
 
 1803    p->setBrush( QBrush( selColor ) );
 
 1809    QTransform t = 
mBrush.transform();
 
 1811    mBrush.setTransform( t );
 
 1816  mBrush.setTransform( bkTransform );
 
 
 1852  return Qt::SolidLine;
 
 1856    return Qt::SolidLine;
 
 1860    return mStroke->dxfPenStyle();
 
 
 1896  , mPatternWidth( width )
 
 1900  mColor = QColor( 255, 255, 255 );
 
 
 1906  , mPatternWidth( width )
 
 1907  , mSvgData( svgData )
 
 1912  mColor = QColor( 255, 255, 255 );
 
 1913  setDefaultSvgParams();
 
 
 1921  mPatternWidthUnit = unit;
 
 1922  mSvgStrokeWidthUnit = unit;
 
 1925    mStroke->setOutputUnit( unit );
 
 
 1931  if ( mPatternWidthUnit != unit || mSvgStrokeWidthUnit != unit || 
mStrokeWidthUnit != unit )
 
 
 1941  mPatternWidthMapUnitScale = scale;
 
 1942  mSvgStrokeWidthMapUnitScale = scale;
 
 
 1948       mPatternWidthMapUnitScale == mSvgStrokeWidthMapUnitScale &&
 
 1951    return mPatternWidthMapUnitScale;
 
 
 1961  mSvgFilePath = svgPath;
 
 1962  setDefaultSvgParams();
 
 
 1972  if ( 
properties.contains( QStringLiteral( 
"width" ) ) )
 
 1974    width = 
properties[QStringLiteral( 
"width" )].toDouble();
 
 1976  if ( 
properties.contains( QStringLiteral( 
"svgFile" ) ) )
 
 1980  if ( 
properties.contains( QStringLiteral( 
"angle" ) ) )
 
 1985  std::unique_ptr< QgsSVGFillSymbolLayer > symbolLayer;
 
 1988    symbolLayer = std::make_unique< QgsSVGFillSymbolLayer >( 
svgFilePath, width, 
angle );
 
 1992    if ( 
properties.contains( QStringLiteral( 
"data" ) ) )
 
 1994      data = QByteArray::fromHex( 
properties[QStringLiteral( 
"data" )].toString().toLocal8Bit() );
 
 1996    symbolLayer = std::make_unique< QgsSVGFillSymbolLayer >( data, width, 
angle );
 
 2000  if ( 
properties.contains( QStringLiteral( 
"svgFillColor" ) ) )
 
 2005  else if ( 
properties.contains( QStringLiteral( 
"color" ) ) )
 
 2009  if ( 
properties.contains( QStringLiteral( 
"svgOutlineColor" ) ) )
 
 2014  else if ( 
properties.contains( QStringLiteral( 
"outline_color" ) ) )
 
 2018  else if ( 
properties.contains( QStringLiteral( 
"line_color" ) ) )
 
 2022  if ( 
properties.contains( QStringLiteral( 
"svgOutlineWidth" ) ) )
 
 2025    symbolLayer->setSvgStrokeWidth( 
properties[QStringLiteral( 
"svgOutlineWidth" )].toDouble() );
 
 2027  else if ( 
properties.contains( QStringLiteral( 
"outline_width" ) ) )
 
 2029    symbolLayer->setSvgStrokeWidth( 
properties[QStringLiteral( 
"outline_width" )].toDouble() );
 
 2031  else if ( 
properties.contains( QStringLiteral( 
"line_width" ) ) )
 
 2033    symbolLayer->setSvgStrokeWidth( 
properties[QStringLiteral( 
"line_width" )].toDouble() );
 
 2037  if ( 
properties.contains( QStringLiteral( 
"pattern_width_unit" ) ) )
 
 2041  if ( 
properties.contains( QStringLiteral( 
"pattern_width_map_unit_scale" ) ) )
 
 2045  if ( 
properties.contains( QStringLiteral( 
"svg_outline_width_unit" ) ) )
 
 2049  if ( 
properties.contains( QStringLiteral( 
"svg_outline_width_map_unit_scale" ) ) )
 
 2053  if ( 
properties.contains( QStringLiteral( 
"outline_width_unit" ) ) )
 
 2057  if ( 
properties.contains( QStringLiteral( 
"outline_width_map_unit_scale" ) ) )
 
 2062  if ( 
properties.contains( QStringLiteral( 
"parameters" ) ) )
 
 2068  symbolLayer->restoreOldDataDefinedProperties( 
properties );
 
 2070  return symbolLayer.release();
 
 
 2075  QVariantMap::iterator it = 
properties.find( QStringLiteral( 
"svgFile" ) );
 
 
 2087  return QStringLiteral( 
"SVGFill" );
 
 
 2090void QgsSVGFillSymbolLayer::applyPattern( QBrush &brush, 
const QString &svgFilePath, 
double patternWidth, 
Qgis::RenderUnit patternWidthUnit,
 
 2091    const QColor &svgFillColor, 
const QColor &svgStrokeColor, 
double svgStrokeWidth,
 
 2095  if ( mSvgViewBox.isNull() )
 
 2102  if ( 
static_cast< int >( size ) < 1.0 || 10000.0 < size )
 
 2104    brush.setTextureImage( QImage() );
 
 2108    bool fitsInCache = 
true;
 
 2116      double hwRatio = 1.0;
 
 2117      if ( patternPict.width() > 0 )
 
 2119        hwRatio = 
static_cast< double >( patternPict.height() ) / 
static_cast< double >( patternPict.width() );
 
 2121      patternImage = QImage( 
static_cast< int >( size ), 
static_cast< int >( size * hwRatio ), QImage::Format_ARGB32_Premultiplied );
 
 2122      patternImage.fill( 0 ); 
 
 2124      QPainter p( &patternImage );
 
 2125      p.drawPicture( QPointF( size / 2, size * hwRatio / 2 ), patternPict );
 
 2128    QTransform brushTransform;
 
 2131      QImage transparentImage = patternImage.copy();
 
 2133      brush.setTextureImage( transparentImage );
 
 2137      brush.setTextureImage( patternImage );
 
 2139    brush.setTransform( brushTransform );
 
 2147  applyPattern( 
mBrush, mSvgFilePath, mPatternWidth, mPatternWidthUnit, 
mColor, mSvgStrokeColor, mSvgStrokeWidth, mSvgStrokeWidthUnit, context, mPatternWidthMapUnitScale, mSvgStrokeWidthMapUnitScale, evaluatedParameters );
 
 
 2170    mStroke->renderPolyline( points, context.
feature(), context.
renderContext(), -1, useSelectedColor );
 
 2173      for ( 
auto ringIt = rings->constBegin(); ringIt != rings->constEnd(); ++ringIt )
 
 2175        mStroke->renderPolyline( *ringIt, context.
feature(), context.
renderContext(), -1, useSelectedColor );
 
 
 2184  if ( !mSvgFilePath.isEmpty() )
 
 2186    map.insert( QStringLiteral( 
"svgFile" ), mSvgFilePath );
 
 2190    map.insert( QStringLiteral( 
"data" ), QString( mSvgData.toHex() ) );
 
 2193  map.insert( QStringLiteral( 
"width" ), QString::number( mPatternWidth ) );
 
 2194  map.insert( QStringLiteral( 
"angle" ), QString::number( 
mAngle ) );
 
 2199  map.insert( QStringLiteral( 
"outline_width" ), QString::number( mSvgStrokeWidth ) );
 
 
 2216  std::unique_ptr< QgsSVGFillSymbolLayer > clonedLayer;
 
 2217  if ( !mSvgFilePath.isEmpty() )
 
 2219    clonedLayer = std::make_unique< QgsSVGFillSymbolLayer >( mSvgFilePath, mPatternWidth, 
mAngle );
 
 2220    clonedLayer->setSvgFillColor( 
mColor );
 
 2221    clonedLayer->setSvgStrokeColor( mSvgStrokeColor );
 
 2222    clonedLayer->setSvgStrokeWidth( mSvgStrokeWidth );
 
 2226    clonedLayer = std::make_unique< QgsSVGFillSymbolLayer >( mSvgData, mPatternWidth, 
mAngle );
 
 2229  clonedLayer->setPatternWidthUnit( mPatternWidthUnit );
 
 2230  clonedLayer->setPatternWidthMapUnitScale( mPatternWidthMapUnitScale );
 
 2231  clonedLayer->setSvgStrokeWidthUnit( mSvgStrokeWidthUnit );
 
 2232  clonedLayer->setSvgStrokeWidthMapUnitScale( mSvgStrokeWidthMapUnitScale );
 
 2236  clonedLayer->setParameters( mParameters );
 
 2240    clonedLayer->setSubSymbol( mStroke->clone() );
 
 2244  return clonedLayer.release();
 
 
 2249  QDomElement symbolizerElem = doc.createElement( QStringLiteral( 
"se:PolygonSymbolizer" ) );
 
 2250  if ( !props.value( QStringLiteral( 
"uom" ), QString() ).toString().isEmpty() )
 
 2251    symbolizerElem.setAttribute( QStringLiteral( 
"uom" ), props.value( QStringLiteral( 
"uom" ), QString() ).toString() );
 
 2252  element.appendChild( symbolizerElem );
 
 2256  QDomElement fillElem = doc.createElement( QStringLiteral( 
"se:Fill" ) );
 
 2257  symbolizerElem.appendChild( fillElem );
 
 2259  QDomElement graphicFillElem = doc.createElement( QStringLiteral( 
"se:GraphicFill" ) );
 
 2260  fillElem.appendChild( graphicFillElem );
 
 2262  QDomElement graphicElem = doc.createElement( QStringLiteral( 
"se:Graphic" ) );
 
 2263  graphicFillElem.appendChild( graphicElem );
 
 2265  if ( !mSvgFilePath.isEmpty() )
 
 2276    symbolizerElem.appendChild( doc.createComment( QStringLiteral( 
"SVG from data not implemented yet" ) ) );
 
 2282  double angle = props.value( QStringLiteral( 
"angle" ), QStringLiteral( 
"0" ) ).toDouble( &ok );
 
 2285    angleFunc = QStringLiteral( 
"%1 + %2" ).arg( props.value( QStringLiteral( 
"angle" ), QStringLiteral( 
"0" ) ).toString() ).arg( 
mAngle );
 
 2298    mStroke->toSld( doc, element, props );
 
 
 2310  return mStroke.get();
 
 
 2317    mStroke.reset( 
nullptr );
 
 2330    mStroke.reset( lineSymbol );
 
 
 2340  if ( mStroke && mStroke->symbolLayer( 0 ) )
 
 2342    double subLayerBleed = mStroke->symbolLayer( 0 )->estimateMaxBleed( context );
 
 2343    return subLayerBleed;
 
 
 2353    return QColor( Qt::black );
 
 2355  return mStroke->color();
 
 
 2362    attr.unite( mStroke->usedAttributes( context ) );
 
 
 2370  if ( mStroke && mStroke->hasDataDefinedProperties() )
 
 
 2377  QString path, mimeType;
 
 2379  Qt::PenStyle penStyle;
 
 2380  double size, strokeWidth;
 
 2382  QDomElement fillElem = element.firstChildElement( QStringLiteral( 
"Fill" ) );
 
 2383  if ( fillElem.isNull() )
 
 2386  QDomElement graphicFillElem = fillElem.firstChildElement( QStringLiteral( 
"GraphicFill" ) );
 
 2387  if ( graphicFillElem.isNull() )
 
 2390  QDomElement graphicElem = graphicFillElem.firstChildElement( QStringLiteral( 
"Graphic" ) );
 
 2391  if ( graphicElem.isNull() )
 
 2397  if ( mimeType != QLatin1String( 
"image/svg+xml" ) )
 
 2402  double scaleFactor = 1.0;
 
 2403  const QString uom = element.attribute( QStringLiteral( 
"uom" ) );
 
 2405  size = size * scaleFactor;
 
 2406  strokeWidth = strokeWidth * scaleFactor;
 
 2413    double d = angleFunc.toDouble( &ok );
 
 2418  std::unique_ptr< QgsSVGFillSymbolLayer > sl = std::make_unique< QgsSVGFillSymbolLayer >( path, size, 
angle );
 
 2419  sl->setOutputUnit( sldUnitSize );
 
 2422  sl->setSvgStrokeWidth( strokeWidth );
 
 2425  QDomElement strokeElem = element.firstChildElement( QStringLiteral( 
"Stroke" ) );
 
 2426  if ( !strokeElem.isNull() )
 
 2437  return sl.release();
 
 
 2455  double width = mPatternWidth;
 
 2461  QString svgFile = mSvgFilePath;
 
 2480  double strokeWidth = mSvgStrokeWidth;
 
 2489                mSvgStrokeWidthUnit, context, mPatternWidthMapUnitScale, mSvgStrokeWidthMapUnitScale, evaluatedParameters );
 
 
 2493void QgsSVGFillSymbolLayer::storeViewBox()
 
 2495  if ( !mSvgData.isEmpty() )
 
 2497    QSvgRenderer r( mSvgData );
 
 2500      mSvgViewBox = r.viewBoxF();
 
 2505  mSvgViewBox = QRectF();
 
 2508void QgsSVGFillSymbolLayer::setDefaultSvgParams()
 
 2510  if ( mSvgFilePath.isEmpty() )
 
 2515  bool hasFillParam, hasFillOpacityParam, hasStrokeParam, hasStrokeWidthParam, hasStrokeOpacityParam;
 
 2516  bool hasDefaultFillColor, hasDefaultFillOpacity, hasDefaultStrokeColor, hasDefaultStrokeWidth, hasDefaultStrokeOpacity;
 
 2517  QColor defaultFillColor, defaultStrokeColor;
 
 2518  double defaultStrokeWidth, defaultFillOpacity, defaultStrokeOpacity;
 
 2520      hasFillOpacityParam, hasDefaultFillOpacity, defaultFillOpacity,
 
 2521      hasStrokeParam, hasDefaultStrokeColor, defaultStrokeColor,
 
 2522      hasStrokeWidthParam, hasDefaultStrokeWidth, defaultStrokeWidth,
 
 2523      hasStrokeOpacityParam, hasDefaultStrokeOpacity, defaultStrokeOpacity );
 
 2525  double newFillOpacity = hasFillOpacityParam ? 
mColor.alphaF() : 1.0;
 
 2526  double newStrokeOpacity = hasStrokeOpacityParam ? mSvgStrokeColor.alphaF() : 1.0;
 
 2528  if ( hasDefaultFillColor )
 
 2530    mColor = defaultFillColor;
 
 2531    mColor.setAlphaF( newFillOpacity );
 
 2533  if ( hasDefaultFillOpacity )
 
 2535    mColor.setAlphaF( defaultFillOpacity );
 
 2537  if ( hasDefaultStrokeColor )
 
 2539    mSvgStrokeColor = defaultStrokeColor;
 
 2540    mSvgStrokeColor.setAlphaF( newStrokeOpacity );
 
 2542  if ( hasDefaultStrokeOpacity )
 
 2544    mSvgStrokeColor.setAlphaF( defaultStrokeOpacity );
 
 2546  if ( hasDefaultStrokeWidth )
 
 2548    mSvgStrokeWidth = defaultStrokeWidth;
 
 2561  mFillLineSymbol = std::make_unique<QgsLineSymbol>( );
 
 
 2569  mFillLineSymbol->setWidth( w );
 
 
 2575  mFillLineSymbol->setColor( 
c );
 
 
 2581  return mFillLineSymbol ? mFillLineSymbol->color() : 
mColor;
 
 
 2593    mFillLineSymbol.reset( qgis::down_cast<QgsLineSymbol *>( symbol ) );
 
 
 2602  return mFillLineSymbol.get();
 
 
 2608  if ( mFillLineSymbol )
 
 2609    attr.unite( mFillLineSymbol->usedAttributes( context ) );
 
 
 2617  if ( mFillLineSymbol && mFillLineSymbol->hasDataDefinedProperties() )
 
 
 2639  double lineAngleRad { qDegreesToRadians( mLineAngle ) };
 
 2641  const int quadrant { 
static_cast<int>( lineAngleRad / M_PI_2 ) };
 
 2642  Q_ASSERT( quadrant >= 0 && quadrant <= 3 );
 
 2652      lineAngleRad -= M_PI / 2;
 
 2657      lineAngleRad -= M_PI;
 
 2662      lineAngleRad -= M_PI + M_PI_2;
 
 2670  QSize size { 
static_cast<int>( distancePx ), 
static_cast<int>( distancePx ) };
 
 2672  if ( 
static_cast<int>( mLineAngle ) % 90 != 0 )
 
 2674    size = QSize( 
static_cast<int>( distancePx / std::sin( lineAngleRad ) ), 
static_cast<int>( distancePx / std::cos( lineAngleRad ) ) );
 
 2677  QPixmap pixmap( size );
 
 2678  pixmap.fill( Qt::transparent );
 
 2680  painter.begin( &pixmap );
 
 2681  painter.setRenderHint( QPainter::Antialiasing );
 
 2689  std::unique_ptr< QgsLinePatternFillSymbolLayer > layerClone( 
clone() );
 
 2690  layerClone->setOffset( 0 );
 
 2691  layerClone->drawPreviewIcon( symbolContext, pixmap.size() );
 
 2693  return pixmap.toImage();
 
 
 2705  mDistanceUnit = unit;
 
 2706  mLineWidthUnit = unit;
 
 2709  if ( mFillLineSymbol )
 
 2710    mFillLineSymbol->setOutputUnit( unit );
 
 
 2733  mDistanceMapUnitScale = scale;
 
 2734  mLineWidthMapUnitScale = scale;
 
 2735  mOffsetMapUnitScale = scale;
 
 
 2741       mDistanceMapUnitScale == mLineWidthMapUnitScale &&
 
 2742       mLineWidthMapUnitScale == mOffsetMapUnitScale )
 
 2744    return mDistanceMapUnitScale;
 
 
 2751  std::unique_ptr< QgsLinePatternFillSymbolLayer > patternLayer = std::make_unique< QgsLinePatternFillSymbolLayer >();
 
 2757  QColor 
color( Qt::black );
 
 2760  if ( 
properties.contains( QStringLiteral( 
"lineangle" ) ) )
 
 2765  else if ( 
properties.contains( QStringLiteral( 
"angle" ) ) )
 
 2769  patternLayer->setLineAngle( 
lineAngle );
 
 2771  if ( 
properties.contains( QStringLiteral( 
"distance" ) ) )
 
 2775  patternLayer->setDistance( 
distance );
 
 2777  if ( 
properties.contains( QStringLiteral( 
"linewidth" ) ) )
 
 2782  else if ( 
properties.contains( QStringLiteral( 
"outline_width" ) ) )
 
 2786  else if ( 
properties.contains( QStringLiteral( 
"line_width" ) ) )
 
 2790  patternLayer->setLineWidth( 
lineWidth );
 
 2792  if ( 
properties.contains( QStringLiteral( 
"color" ) ) )
 
 2796  else if ( 
properties.contains( QStringLiteral( 
"outline_color" ) ) )
 
 2800  else if ( 
properties.contains( QStringLiteral( 
"line_color" ) ) )
 
 2804  patternLayer->setColor( 
color );
 
 2806  if ( 
properties.contains( QStringLiteral( 
"offset" ) ) )
 
 2810  patternLayer->setOffset( 
offset );
 
 2813  if ( 
properties.contains( QStringLiteral( 
"distance_unit" ) ) )
 
 2817  if ( 
properties.contains( QStringLiteral( 
"distance_map_unit_scale" ) ) )
 
 2821  if ( 
properties.contains( QStringLiteral( 
"line_width_unit" ) ) )
 
 2825  else if ( 
properties.contains( QStringLiteral( 
"outline_width_unit" ) ) )
 
 2829  if ( 
properties.contains( QStringLiteral( 
"line_width_map_unit_scale" ) ) )
 
 2833  if ( 
properties.contains( QStringLiteral( 
"offset_unit" ) ) )
 
 2837  if ( 
properties.contains( QStringLiteral( 
"offset_map_unit_scale" ) ) )
 
 2841  if ( 
properties.contains( QStringLiteral( 
"outline_width_unit" ) ) )
 
 2845  if ( 
properties.contains( QStringLiteral( 
"outline_width_map_unit_scale" ) ) )
 
 2849  if ( 
properties.contains( QStringLiteral( 
"coordinate_reference" ) ) )
 
 2853  if ( 
properties.contains( QStringLiteral( 
"clip_mode" ) ) )
 
 2858  patternLayer->restoreOldDataDefinedProperties( 
properties );
 
 2860  return patternLayer.release();
 
 
 2865  return QStringLiteral( 
"LinePatternFill" );
 
 
 2868bool QgsLinePatternFillSymbolLayer::applyPattern( 
const QgsSymbolRenderContext &context, QBrush &brush, 
double lineAngle, 
double distance )
 
 2870  mBrush.setTextureImage( QImage() ); 
 
 2872  if ( !mFillLineSymbol )
 
 2877  std::unique_ptr< QgsLineSymbol > fillLineSymbol( mFillLineSymbol->clone() );
 
 2878  if ( !fillLineSymbol )
 
 2894  outputPixelOffset = std::fmod( outputPixelOffset, outputPixelDist );
 
 2895  if ( outputPixelOffset > outputPixelDist / 2.0 )
 
 2896    outputPixelOffset -= outputPixelDist;
 
 2900  double outputPixelBleed = 0;
 
 2901  double outputPixelInterval = 0; 
 
 2902  for ( 
int i = 0; i < fillLineSymbol->symbolLayerCount(); i++ )
 
 2906    outputPixelBleed = std::max( outputPixelBleed, outputPixelLayerBleed );
 
 2909    if ( markerLineLayer )
 
 2918      outputPixelInterval = std::max( outputPixelInterval, outputPixelLayerInterval );
 
 2922  if ( outputPixelInterval > 0 )
 
 2926    double intervalScale = std::round( outputPixelInterval ) / outputPixelInterval;
 
 2927    outputPixelInterval = std::round( outputPixelInterval );
 
 2929    for ( 
int i = 0; i < fillLineSymbol->symbolLayerCount(); i++ )
 
 2934      if ( markerLineLayer )
 
 2948    height = outputPixelDist;
 
 2949    width = outputPixelInterval > 0 ? outputPixelInterval : height;
 
 2953    width = outputPixelDist;
 
 2954    height = outputPixelInterval > 0 ? outputPixelInterval : width;
 
 2958    height = outputPixelDist / std::cos( 
lineAngle * M_PI / 180 ); 
 
 2959    width = outputPixelDist / std::sin( 
lineAngle * M_PI / 180 );
 
 2962    lineAngle = 180 * std::atan2( 
static_cast< double >( height ), 
static_cast< double >( width ) ) / M_PI;
 
 2968    height = std::abs( height );
 
 2969    width = std::abs( width );
 
 2971    outputPixelDist = std::abs( height * std::cos( 
lineAngle * M_PI / 180 ) );
 
 2975    int offsetHeight = 
static_cast< int >( std::round( outputPixelOffset / std::cos( 
lineAngle * M_PI / 180 ) ) );
 
 2976    outputPixelOffset = offsetHeight * std::cos( 
lineAngle * M_PI / 180 );
 
 2985  int bufferMulti = 
static_cast< int >( std::max( std::ceil( outputPixelBleed / width ), std::ceil( outputPixelBleed / width ) ) );
 
 2989  bufferMulti = std::max( bufferMulti, 1 );
 
 2991  int xBuffer = width * bufferMulti;
 
 2992  int yBuffer = height * bufferMulti;
 
 2993  int innerWidth = width;
 
 2994  int innerHeight = height;
 
 2995  width += 2 * xBuffer;
 
 2996  height += 2 * yBuffer;
 
 2999  if ( width > 2000 || height > 2000 || width == 0 || height == 0 )
 
 3004  QImage patternImage( width, height, QImage::Format_ARGB32 );
 
 3005  patternImage.fill( 0 );
 
 3007  QPointF p1, p2, p3, p4, p5, p6;
 
 3010    p1 = QPointF( 0, yBuffer );
 
 3011    p2 = QPointF( width, yBuffer );
 
 3012    p3 = QPointF( 0, yBuffer + innerHeight );
 
 3013    p4 = QPointF( width, yBuffer + innerHeight );
 
 3017    p1 = QPointF( xBuffer, height );
 
 3018    p2 = QPointF( xBuffer, 0 );
 
 3019    p3 = QPointF( xBuffer + innerWidth, height );
 
 3020    p4 = QPointF( xBuffer + innerWidth, 0 );
 
 3024    dx = outputPixelDist * std::cos( ( 90 - 
lineAngle ) * M_PI / 180.0 );
 
 3025    dy = outputPixelDist * std::sin( ( 90 - 
lineAngle ) * M_PI / 180.0 );
 
 3026    p1 = QPointF( 0, height );
 
 3027    p2 = QPointF( width, 0 );
 
 3028    p3 = QPointF( -dx, height - dy );
 
 3029    p4 = QPointF( width - dx, -dy );
 
 3030    p5 = QPointF( dx, height + dy );
 
 3031    p6 = QPointF( width + dx, dy );
 
 3035    dx = outputPixelDist * std::cos( ( 90 - 
lineAngle ) * M_PI / 180.0 );
 
 3036    dy = outputPixelDist * std::sin( ( 90 - 
lineAngle ) * M_PI / 180.0 );
 
 3037    p1 = QPointF( width, 0 );
 
 3038    p2 = QPointF( 0, height );
 
 3039    p3 = QPointF( width - dx, -dy );
 
 3040    p4 = QPointF( -dx, height - dy );
 
 3041    p5 = QPointF( width + dx, dy );
 
 3042    p6 = QPointF( dx, height + dy );
 
 3046    dy = outputPixelDist * std::cos( ( 180 - 
lineAngle ) * M_PI / 180 );
 
 3047    dx = outputPixelDist * std::sin( ( 180 - 
lineAngle ) * M_PI / 180 );
 
 3048    p1 = QPointF( 0, 0 );
 
 3049    p2 = QPointF( width, height );
 
 3050    p5 = QPointF( dx, -dy );
 
 3051    p6 = QPointF( width + dx, height - dy );
 
 3052    p3 = QPointF( -dx, dy );
 
 3053    p4 = QPointF( width - dx, height + dy );
 
 3057    dy = outputPixelDist * std::cos( ( 180 - 
lineAngle ) * M_PI / 180 );
 
 3058    dx = outputPixelDist * std::sin( ( 180 - 
lineAngle ) * M_PI / 180 );
 
 3059    p1 = QPointF( width, height );
 
 3060    p2 = QPointF( 0, 0 );
 
 3061    p5 = QPointF( width + dx, height - dy );
 
 3062    p6 = QPointF( dx, -dy );
 
 3063    p3 = QPointF( width - dx, height + dy );
 
 3064    p4 = QPointF( -dx, dy );
 
 3071    p3 = QPointF( tempPt.x(), tempPt.y() );
 
 3073    p4 = QPointF( tempPt.x(), tempPt.y() );
 
 3075    p5 = QPointF( tempPt.x(), tempPt.y() );
 
 3077    p6 = QPointF( tempPt.x(), tempPt.y() );
 
 3081    p1 = QPointF( tempPt.x(), tempPt.y() );
 
 3083    p2 = QPointF( tempPt.x(), tempPt.y() );
 
 3086  QPainter p( &patternImage );
 
 3090  p.setRenderHint( QPainter::Antialiasing, 
false ); 
 
 3091  QPen pen( QColor( Qt::black ) );
 
 3092  pen.setWidthF( 0.1 );
 
 3093  pen.setCapStyle( Qt::FlatCap );
 
 3098  QPolygon polygon = QPolygon() << QPoint( 0, 0 ) << QPoint( width - 1, 0 ) << QPoint( width - 1, height - 1 ) << QPoint( 0, height - 1 ) << QPoint( 0, 0 );
 
 3099  p.drawPolygon( polygon );
 
 3101  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 );
 
 3102  p.drawPolygon( polygon );
 
 3108  p.setRenderHint( QPainter::Antialiasing, 
true );
 
 3121  fillLineSymbol->startRender( lineRenderContext, context.
fields() );
 
 3123  QVector<QPolygonF> polygons;
 
 3124  polygons.append( QPolygonF() << p1 << p2 );
 
 3125  polygons.append( QPolygonF() << p3 << p4 );
 
 3128    polygons.append( QPolygonF() << p5 << p6 );
 
 3132  for ( 
const QPolygonF &polygon : std::as_const( polygons ) )
 
 3134    fillLineSymbol->renderPolyline( polygon, context.
feature(), lineRenderContext, -1, useSelectedColor );
 
 3137  fillLineSymbol->stopRender( lineRenderContext );
 
 3141  patternImage = patternImage.copy( xBuffer, yBuffer, patternImage.width() - 2 * xBuffer, patternImage.height() - 2 * yBuffer );
 
 3146    QImage transparentImage = patternImage.copy();
 
 3148    brush.setTextureImage( transparentImage );
 
 3152    brush.setTextureImage( patternImage );
 
 3155  QTransform brushTransform;
 
 3156  brush.setTransform( brushTransform );
 
 3166                      || ( mFillLineSymbol && mFillLineSymbol->hasDataDefinedProperties() )
 
 3170  if ( !mRenderUsingLines )
 
 3174    mRenderUsingLines = !applyPattern( context, 
mBrush, mLineAngle, mDistance );
 
 3177  if ( mRenderUsingLines && mFillLineSymbol )
 
 3180    mFillLineSymbolRenderStarted = 
true;
 
 
 3186  if ( mFillLineSymbolRenderStarted )
 
 3189    mFillLineSymbolRenderStarted = 
false;
 
 
 3196  if ( !useSelectedColor && !mRenderUsingLines )
 
 3203  if ( !mFillLineSymbolRenderStarted && mFillLineSymbol )
 
 3206    mFillLineSymbolRenderStarted = 
true;
 
 3236  outputPixelOffset = std::fmod( outputPixelOffset, outputPixelDistance );
 
 3237  if ( outputPixelOffset > outputPixelDistance / 2.0 )
 
 3238    outputPixelOffset -= outputPixelDistance;
 
 3240  p->setPen( QPen( Qt::NoPen ) );
 
 3262  std::unique_ptr< QgsPolygon > shapePolygon;
 
 3263  std::unique_ptr< QgsGeometryEngine > shapeEngine;
 
 3271      shapePolygon = std::make_unique< QgsPolygon >();
 
 3275        for ( 
const QPolygonF &ring : *rings )
 
 3281      shapeEngine->prepareGeometry();
 
 3288      path.addPolygon( points );
 
 3291        for ( 
const QPolygonF &ring : *rings )
 
 3293          path.addPolygon( ring );
 
 3296      p->setClipPath( path, Qt::IntersectClip );
 
 3302  const QRectF boundingRect = points.boundingRect();
 
 3304  QTransform invertedRotateTransform;
 
 3310  QTransform transform;
 
 3311  if ( applyBrushTransform )
 
 3314    transform.translate( -boundingRect.center().x(),
 
 3315                         -boundingRect.center().y() );
 
 3317    transform.translate( boundingRect.center().x(),
 
 3318                         boundingRect.center().y() );
 
 3326  const QRectF transformedBounds = transform.map( points ).boundingRect();
 
 3330  left = transformedBounds.left() - buffer * 2;
 
 3331  top = transformedBounds.top() - buffer * 2;
 
 3332  right = transformedBounds.right() + buffer * 2;
 
 3333  bottom = transformedBounds.bottom() + buffer * 2;
 
 3334  invertedRotateTransform = transform.inverted();
 
 3336  if ( !applyBrushTransform )
 
 3338    top -= transformedBounds.top() - ( outputPixelDistance * std::floor( transformedBounds.top() / outputPixelDistance ) );
 
 3343  const bool needsExpressionContext = mFillLineSymbol->hasDataDefinedProperties();
 
 3348  int currentLine = 0;
 
 3349  for ( 
double currentY = top; currentY <= bottom; currentY += outputPixelDistance )
 
 3354    if ( needsExpressionContext )
 
 3358    double y1 = currentY;
 
 3360    double y2 = currentY;
 
 3361    invertedRotateTransform.map( left, currentY - outputPixelOffset, &x1, &y1 );
 
 3362    invertedRotateTransform.map( right, currentY - outputPixelOffset, &x2, &y2 );
 
 3367      std::unique_ptr< QgsAbstractGeometry > intersection( shapeEngine->intersection( &ls ) );
 
 3368      for ( 
auto it = intersection->const_parts_begin(); it != intersection->const_parts_end(); ++it )
 
 3370        if ( 
const QgsLineString *ls = qgsgeometry_cast< const QgsLineString * >( *it ) )
 
 3378      mFillLineSymbol->renderPolyline( QPolygonF() << QPointF( x1, y1 ) << QPointF( x2, y2 ), context.
feature(), context.
renderContext(), -1, useSelectedColor );
 
 
 3390  map.insert( QStringLiteral( 
"angle" ), QString::number( mLineAngle ) );
 
 3391  map.insert( QStringLiteral( 
"distance" ), QString::number( mDistance ) );
 
 3392  map.insert( QStringLiteral( 
"line_width" ), QString::number( mLineWidth ) );
 
 3394  map.insert( QStringLiteral( 
"offset" ), QString::number( mOffset ) );
 
 
 3410  if ( mFillLineSymbol )
 
 
 3421  QDomElement symbolizerElem = doc.createElement( QStringLiteral( 
"se:PolygonSymbolizer" ) );
 
 3422  if ( !props.value( QStringLiteral( 
"uom" ), QString() ).toString().isEmpty() )
 
 3423    symbolizerElem.setAttribute( QStringLiteral( 
"uom" ), props.value( QStringLiteral( 
"uom" ), QString() ).toString() );
 
 3424  element.appendChild( symbolizerElem );
 
 3429  QDomElement fillElem = doc.createElement( QStringLiteral( 
"se:Fill" ) );
 
 3430  symbolizerElem.appendChild( fillElem );
 
 3432  QDomElement graphicFillElem = doc.createElement( QStringLiteral( 
"se:GraphicFill" ) );
 
 3433  fillElem.appendChild( graphicFillElem );
 
 3435  QDomElement graphicElem = doc.createElement( QStringLiteral( 
"se:Graphic" ) );
 
 3436  graphicFillElem.appendChild( graphicElem );
 
 3441  bool exportOk { 
false };
 
 3445    if ( ! image.isNull() )
 
 3447      const QFileInfo info { context.exportFilePath() };
 
 3448      QString pngPath { info.completeSuffix().isEmpty() ? context.exportFilePath() : context.exportFilePath().chopped( info.completeSuffix().length() ).append( QStringLiteral( 
"png" ) ) };
 
 3450      image.save( pngPath );
 
 3459    QColor lineColor = mFillLineSymbol ? mFillLineSymbol->color() : QColor();
 
 3460    double lineWidth = mFillLineSymbol ? mFillLineSymbol->width() : 0.0;
 
 3468    double angle = props.value( QStringLiteral( 
"angle" ), QStringLiteral( 
"0" ) ).toDouble( &ok );
 
 3471      angleFunc = QStringLiteral( 
"%1 + %2" ).arg( props.value( QStringLiteral( 
"angle" ), QStringLiteral( 
"0" ) ).toString() ).arg( mLineAngle );
 
 3475      angleFunc = QString::number( 
angle + mLineAngle );
 
 3480    QPointF lineOffset( std::sin( mLineAngle ) * mOffset, std::cos( mLineAngle ) * mOffset );
 
 
 3488  QString featureStyle;
 
 3489  featureStyle.append( 
"Brush(" );
 
 3490  featureStyle.append( QStringLiteral( 
"fc:%1" ).arg( 
mColor.name() ) );
 
 3491  featureStyle.append( QStringLiteral( 
",bc:%1" ).arg( QLatin1String( 
"#00000000" ) ) ); 
 
 3492  featureStyle.append( 
",id:\"ogr-brush-2\"" );
 
 3493  featureStyle.append( QStringLiteral( 
",a:%1" ).arg( mLineAngle ) );
 
 3494  featureStyle.append( QStringLiteral( 
",s:%1" ).arg( mLineWidth * widthScaleFactor ) );
 
 3495  featureStyle.append( 
",dx:0mm" );
 
 3496  featureStyle.append( QStringLiteral( 
",dy:%1mm" ).arg( mDistance * widthScaleFactor ) );
 
 3497  featureStyle.append( 
')' );
 
 3498  return featureStyle;
 
 
 3504       && ( !mFillLineSymbol || !mFillLineSymbol->hasDataDefinedProperties() ) )
 
 
 3529  Qt::PenStyle lineStyle;
 
 3531  QDomElement fillElem = element.firstChildElement( QStringLiteral( 
"Fill" ) );
 
 3532  if ( fillElem.isNull() )
 
 3535  QDomElement graphicFillElem = fillElem.firstChildElement( QStringLiteral( 
"GraphicFill" ) );
 
 3536  if ( graphicFillElem.isNull() )
 
 3539  QDomElement graphicElem = graphicFillElem.firstChildElement( QStringLiteral( 
"Graphic" ) );
 
 3540  if ( graphicElem.isNull() )
 
 3546  if ( name != QLatin1String( 
"horline" ) )
 
 3554    double d = angleFunc.toDouble( &ok );
 
 3563    offset = std::sqrt( std::pow( vectOffset.x(), 2 ) + std::pow( vectOffset.y(), 2 ) );
 
 3566  double scaleFactor = 1.0;
 
 3567  const QString uom = element.attribute( QStringLiteral( 
"uom" ) );
 
 3569  size = size * scaleFactor;
 
 3572  std::unique_ptr< QgsLinePatternFillSymbolLayer > sl = std::make_unique< QgsLinePatternFillSymbolLayer >();
 
 3573  sl->setOutputUnit( sldUnitSize );
 
 3574  sl->setColor( lineColor );
 
 3576  sl->setLineAngle( 
angle );
 
 3578  sl->setDistance( size );
 
 3581  QDomElement strokeElem = element.firstChildElement( QStringLiteral( 
"Stroke" ) );
 
 3582  if ( !strokeElem.isNull() )
 
 3593  return sl.release();
 
 
 3693  std::unique_ptr< QgsPointPatternFillSymbolLayer > layer = std::make_unique< QgsPointPatternFillSymbolLayer >();
 
 3694  if ( 
properties.contains( QStringLiteral( 
"distance_x" ) ) )
 
 3696    layer->setDistanceX( 
properties[QStringLiteral( 
"distance_x" )].toDouble() );
 
 3698  if ( 
properties.contains( QStringLiteral( 
"distance_y" ) ) )
 
 3700    layer->setDistanceY( 
properties[QStringLiteral( 
"distance_y" )].toDouble() );
 
 3702  if ( 
properties.contains( QStringLiteral( 
"displacement_x" ) ) )
 
 3704    layer->setDisplacementX( 
properties[QStringLiteral( 
"displacement_x" )].toDouble() );
 
 3706  if ( 
properties.contains( QStringLiteral( 
"displacement_y" ) ) )
 
 3708    layer->setDisplacementY( 
properties[QStringLiteral( 
"displacement_y" )].toDouble() );
 
 3710  if ( 
properties.contains( QStringLiteral( 
"offset_x" ) ) )
 
 3712    layer->setOffsetX( 
properties[QStringLiteral( 
"offset_x" )].toDouble() );
 
 3714  if ( 
properties.contains( QStringLiteral( 
"offset_y" ) ) )
 
 3716    layer->setOffsetY( 
properties[QStringLiteral( 
"offset_y" )].toDouble() );
 
 3719  if ( 
properties.contains( QStringLiteral( 
"distance_x_unit" ) ) )
 
 3723  if ( 
properties.contains( QStringLiteral( 
"distance_x_map_unit_scale" ) ) )
 
 3727  if ( 
properties.contains( QStringLiteral( 
"distance_y_unit" ) ) )
 
 3731  if ( 
properties.contains( QStringLiteral( 
"distance_y_map_unit_scale" ) ) )
 
 3735  if ( 
properties.contains( QStringLiteral( 
"displacement_x_unit" ) ) )
 
 3739  if ( 
properties.contains( QStringLiteral( 
"displacement_x_map_unit_scale" ) ) )
 
 3743  if ( 
properties.contains( QStringLiteral( 
"displacement_y_unit" ) ) )
 
 3747  if ( 
properties.contains( QStringLiteral( 
"displacement_y_map_unit_scale" ) ) )
 
 3751  if ( 
properties.contains( QStringLiteral( 
"offset_x_unit" ) ) )
 
 3755  if ( 
properties.contains( QStringLiteral( 
"offset_x_map_unit_scale" ) ) )
 
 3759  if ( 
properties.contains( QStringLiteral( 
"offset_y_unit" ) ) )
 
 3763  if ( 
properties.contains( QStringLiteral( 
"offset_y_map_unit_scale" ) ) )
 
 3768  if ( 
properties.contains( QStringLiteral( 
"random_deviation_x" ) ) )
 
 3770    layer->setMaximumRandomDeviationX( 
properties[QStringLiteral( 
"random_deviation_x" )].toDouble() );
 
 3772  if ( 
properties.contains( QStringLiteral( 
"random_deviation_y" ) ) )
 
 3774    layer->setMaximumRandomDeviationY( 
properties[QStringLiteral( 
"random_deviation_y" )].toDouble() );
 
 3776  if ( 
properties.contains( QStringLiteral( 
"random_deviation_x_unit" ) ) )
 
 3780  if ( 
properties.contains( QStringLiteral( 
"random_deviation_x_map_unit_scale" ) ) )
 
 3784  if ( 
properties.contains( QStringLiteral( 
"random_deviation_y_unit" ) ) )
 
 3788  if ( 
properties.contains( QStringLiteral( 
"random_deviation_y_map_unit_scale" ) ) )
 
 3792  unsigned long seed = 0;
 
 3793  if ( 
properties.contains( QStringLiteral( 
"seed" ) ) )
 
 3799    std::random_device rd;
 
 3800    std::mt19937 mt( 
seed == 0 ? rd() : 
seed );
 
 3801    std::uniform_int_distribution<> uniformDist( 1, 999999999 );
 
 3802    seed = uniformDist( mt );
 
 3804  layer->setSeed( 
seed );
 
 3806  if ( 
properties.contains( QStringLiteral( 
"outline_width_unit" ) ) )
 
 3810  if ( 
properties.contains( QStringLiteral( 
"outline_width_map_unit_scale" ) ) )
 
 3814  if ( 
properties.contains( QStringLiteral( 
"clip_mode" ) ) )
 
 3818  if ( 
properties.contains( QStringLiteral( 
"coordinate_reference" ) ) )
 
 3823  if ( 
properties.contains( QStringLiteral( 
"angle" ) ) )
 
 3825    layer->setAngle( 
properties[QStringLiteral( 
"angle" )].toDouble() );
 
 3828  layer->restoreOldDataDefinedProperties( 
properties );
 
 3830  return layer.release();
 
 
 3835  return QStringLiteral( 
"PointPatternFill" );
 
 
 3838bool QgsPointPatternFillSymbolLayer::applyPattern( 
const QgsSymbolRenderContext &context, QBrush &brush, 
double distanceX, 
double distanceY,
 
 3839    double displacementX, 
double displacementY, 
double offsetX, 
double offsetY )
 
 3846  double widthOffset = std::fmod(
 
 3849  double heightOffset = std::fmod(
 
 3853  if ( width > 2000 || height > 2000 ) 
 
 3855    brush.setTextureImage( QImage() );
 
 3859  QImage patternImage( width, height, QImage::Format_ARGB32 );
 
 3860  patternImage.fill( 0 );
 
 3861  if ( patternImage.isNull() )
 
 3863    brush.setTextureImage( QImage() );
 
 3868    QPainter p( &patternImage );
 
 3886    for ( 
double currentX = -width; currentX <= width * 2.0; currentX += width )
 
 3888      for ( 
double currentY = -height; currentY <= height * 2.0; currentY += height )
 
 3890        mMarkerSymbol->renderPoint( QPointF( currentX + widthOffset, currentY + heightOffset ), context.
feature(), pointRenderContext );
 
 3901    for ( 
double currentX = -width; currentX <= width * 2.0; currentX += width )
 
 3903      for ( 
double currentY = -height / 2.0; currentY <= height * 2.0; currentY += height )
 
 3905        mMarkerSymbol->renderPoint( QPointF( currentX + widthOffset + displacementPixelX, currentY + heightOffset ), context.
feature(), pointRenderContext );
 
 3909    for ( 
double currentX = -width / 2.0; currentX <= width * 2.0; currentX += width )
 
 3911      for ( 
double currentY = -height; currentY <= height * 2.0; currentY += height / 2.0 )
 
 3913        mMarkerSymbol->renderPoint( QPointF( currentX + widthOffset + ( std::fmod( currentY, height ) != 0 ? displacementPixelX : 0 ), currentY + heightOffset - displacementPixelY ), context.feature(), pointRenderContext );
 
 3922    QImage transparentImage = patternImage.copy();
 
 3924    brush.setTextureImage( transparentImage );
 
 3928    brush.setTextureImage( patternImage );
 
 3930  QTransform brushTransform;
 
 3931  brush.setTransform( brushTransform );
 
 3951  if ( !mRenderUsingMarkers )
 
 
 3995  if ( !useSelectedColor && !mRenderUsingMarkers )
 
 4044  const double widthOffset = std::fmod(
 
 4056  const double heightOffset = std::fmod(
 
 4082  p->setPen( QPen( Qt::NoPen ) );
 
 4104  std::unique_ptr< QgsPolygon > shapePolygon;
 
 4105  std::unique_ptr< QgsGeometryEngine > shapeEngine;
 
 4112      shapePolygon = std::make_unique< QgsPolygon >();
 
 4116        for ( 
const QPolygonF &ring : *rings )
 
 4122      shapeEngine->prepareGeometry();
 
 4129      path.addPolygon( points );
 
 4132        for ( 
const QPolygonF &ring : *rings )
 
 4134          path.addPolygon( ring );
 
 4137      p->setClipPath( path, Qt::IntersectClip );
 
 4143  const QRectF boundingRect = points.boundingRect();
 
 4145  QTransform invertedRotateTransform;
 
 4153    QTransform transform;
 
 4154    if ( applyBrushTransform )
 
 4157      transform.translate( -boundingRect.center().x(),
 
 4158                           -boundingRect.center().y() );
 
 4159      transform.rotate( -
angle );
 
 4160      transform.translate( boundingRect.center().x(),
 
 4161                           boundingRect.center().y() );
 
 4166      transform.rotate( -
angle );
 
 4169    const QRectF transformedBounds = transform.map( points ).boundingRect();
 
 4170    left = transformedBounds.left() - 2 * width;
 
 4171    top = transformedBounds.top() - 2 * height;
 
 4172    right = transformedBounds.right() + 2 * width;
 
 4173    bottom = transformedBounds.bottom() + 2 * height;
 
 4174    invertedRotateTransform = transform.inverted();
 
 4176    if ( !applyBrushTransform )
 
 4178      left -= transformedBounds.left() - ( width * std::floor( transformedBounds.left() / width ) );
 
 4179      top -= transformedBounds.top() - ( height * std::floor( transformedBounds.top() / height ) );
 
 4184    left = boundingRect.left() - 2 * width;
 
 4185    top = boundingRect.top() - 2 * height;
 
 4186    right = boundingRect.right() + 2 * width;
 
 4187    bottom = boundingRect.bottom() + 2 * height;
 
 4189    if ( !applyBrushTransform )
 
 4191      left -= boundingRect.left() - ( width * std::floor( boundingRect.left() / width ) );
 
 4192      top -= boundingRect.top() - ( height * std::floor( boundingRect.top() / height ) );
 
 4221  std::random_device rd;
 
 4222  std::mt19937 mt( 
seed == 0 ? rd() : 
seed );
 
 4223  std::uniform_real_distribution<> uniformDist( 0, 1 );
 
 4229  const bool needsExpressionContext = 
mMarkerSymbol->hasDataDefinedProperties();
 
 4237  bool alternateColumn = 
false;
 
 4238  int currentCol = -3; 
 
 4239  for ( 
double currentX = left; currentX <= right; currentX += width, alternateColumn = !alternateColumn )
 
 4244    if ( needsExpressionContext )
 
 4247    bool alternateRow = 
false;
 
 4248    const double columnX = currentX + widthOffset;
 
 4249    int currentRow = -3;
 
 4250    for ( 
double currentY = top; currentY <= bottom; currentY += height, alternateRow = !alternateRow )
 
 4255      double y = currentY + heightOffset;
 
 4258        x += displacementPixelX;
 
 4260      if ( !alternateColumn )
 
 4261        y -= displacementPixelY;
 
 4267        invertedRotateTransform.map( xx, yy, &x, &y );
 
 4270      if ( useRandomShift )
 
 4272        x += ( 2 * uniformDist( mt ) - 1 ) * maxRandomDeviationPixelX;
 
 4273        y += ( 2 * uniformDist( mt ) - 1 ) * maxRandomDeviationPixelY;
 
 4276      if ( needsExpressionContext )
 
 4284        bool renderPoint = 
true;
 
 4292            renderPoint = shapeEngine->intersects( &p );
 
 4304              renderPoint = shapeEngine->intersects( markerBounds.
constGet() );
 
 
 4330  map.insert( QStringLiteral( 
"distance_x" ), QString::number( 
mDistanceX ) );
 
 4331  map.insert( QStringLiteral( 
"distance_y" ), QString::number( 
mDistanceY ) );
 
 4332  map.insert( QStringLiteral( 
"displacement_x" ), QString::number( 
mDisplacementX ) );
 
 4333  map.insert( QStringLiteral( 
"displacement_y" ), QString::number( 
mDisplacementY ) );
 
 4334  map.insert( QStringLiteral( 
"offset_x" ), QString::number( 
mOffsetX ) );
 
 4335  map.insert( QStringLiteral( 
"offset_y" ), QString::number( 
mOffsetY ) );
 
 4351  map.insert( QStringLiteral( 
"random_deviation_x" ), QString::number( 
mRandomDeviationX ) );
 
 4352  map.insert( QStringLiteral( 
"random_deviation_y" ), QString::number( 
mRandomDeviationY ) );
 
 4357  map.insert( QStringLiteral( 
"seed" ), QString::number( 
mSeed ) );
 
 4358  map.insert( QStringLiteral( 
"angle" ), 
mAngle );
 
 
 4377  for ( 
int symbolLayerIdx = 0; symbolLayerIdx < 
mMarkerSymbol->symbolLayerCount(); symbolLayerIdx++ )
 
 4379    QDomElement symbolizerElem = doc.createElement( QStringLiteral( 
"se:PolygonSymbolizer" ) );
 
 4380    if ( !props.value( QStringLiteral( 
"uom" ), QString() ).toString().isEmpty() )
 
 4381      symbolizerElem.setAttribute( QStringLiteral( 
"uom" ), props.value( QStringLiteral( 
"uom" ), QString() ).toString() );
 
 4382    element.appendChild( symbolizerElem );
 
 4387    QDomElement fillElem = doc.createElement( QStringLiteral( 
"se:Fill" ) );
 
 4388    symbolizerElem.appendChild( fillElem );
 
 4390    QDomElement graphicFillElem = doc.createElement( QStringLiteral( 
"se:GraphicFill" ) );
 
 4391    fillElem.appendChild( graphicFillElem );
 
 4398    bool exportOk { 
false };
 
 4402      if ( ! image.isNull() )
 
 4404        QDomElement graphicElem = doc.createElement( QStringLiteral( 
"se:Graphic" ) );
 
 4405        graphicFillElem.appendChild( graphicElem );
 
 4406        const QFileInfo info { context.exportFilePath() };
 
 4407        QString pngPath { info.completeSuffix().isEmpty() ? context.exportFilePath() : context.exportFilePath().chopped( info.completeSuffix().length() ).append( QStringLiteral( 
"png" ) ) };
 
 4409        image.save( pngPath );
 
 4428      symbolizerElem.appendChild( graphicMarginElem );
 
 4432        markerLayer->writeSldMarker( doc, graphicFillElem, props );
 
 4436        QString errorMsg = QStringLiteral( 
"QgsMarkerSymbolLayer expected, %1 found. Skip it." ).arg( layer->
layerType() );
 
 4437        graphicFillElem.appendChild( doc.createComment( errorMsg ) );
 
 4441        QString errorMsg = QStringLiteral( 
"Missing point pattern symbol layer. Skip it." );
 
 4442        graphicFillElem.appendChild( doc.createComment( errorMsg ) );
 
 
 4451  double angleRads { qDegreesToRadians( 
mAngle ) };
 
 4460  if ( displacementXPx != 0 )
 
 4465  if ( displacementYPx != 0 )
 
 4472  QPixmap pixmap( size );
 
 4473  pixmap.fill( Qt::transparent );
 
 4475  painter.begin( &pixmap );
 
 4476  painter.setRenderHint( QPainter::Antialiasing );
 
 4484  std::unique_ptr< QgsPointPatternFillSymbolLayer > layerClone( 
clone() );
 
 4486  layerClone->setAngle( qRadiansToDegrees( angleRads ) );
 
 4489  layerClone->setMaximumRandomDeviationX( 0 );
 
 4490  layerClone->setMaximumRandomDeviationY( 0 );
 
 4492  layerClone->drawPreviewIcon( symbolContext, pixmap.size() );
 
 4494  return pixmap.toImage();
 
 
 4502  QDomElement fillElem = element.firstChildElement( QStringLiteral( 
"Fill" ) );
 
 4503  if ( fillElem.isNull() )
 
 4506  QDomElement graphicFillElem = fillElem.firstChildElement( QStringLiteral( 
"GraphicFill" ) );
 
 4507  if ( graphicFillElem.isNull() )
 
 4510  QDomElement graphicElem = graphicFillElem.firstChildElement( QStringLiteral( 
"Graphic" ) );
 
 4511  if ( graphicElem.isNull() )
 
 4515  if ( !simpleMarkerSl )
 
 4520  layers.append( simpleMarkerSl );
 
 4522  std::unique_ptr< QgsMarkerSymbol > marker = std::make_unique< QgsMarkerSymbol >( layers );
 
 4525  const double markerSize { marker->size() };
 
 4527  std::unique_ptr< QgsPointPatternFillSymbolLayer > pointPatternFillSl = std::make_unique< QgsPointPatternFillSymbolLayer >();
 
 4528  pointPatternFillSl->setSubSymbol( marker.release() );
 
 4533  auto distanceParser = [ & ]( 
const QStringList & values )
 
 4535    switch ( values.count( ) )
 
 4540        const double v { values.at( 0 ).toDouble( &ok ) };
 
 4543          pointPatternFillSl->setDistanceX( v * 2 + markerSize );
 
 4544          pointPatternFillSl->setDistanceY( v * 2 + markerSize );
 
 4551        const double vX { values.at( 1 ).toDouble( &ok ) };
 
 4554          pointPatternFillSl->setDistanceX( vX * 2 + markerSize );
 
 4556        const double vY { values.at( 0 ).toDouble( &ok ) };
 
 4559          pointPatternFillSl->setDistanceY( vY * 2 + markerSize );
 
 4566        const double vX { values.at( 1 ).toDouble( &ok ) };
 
 4569          pointPatternFillSl->setDistanceX( vX * 2 + markerSize );
 
 4571        const double vYt { values.at( 0 ).toDouble( &ok ) };
 
 4574          const double vYb { values.at( 2 ).toDouble( &ok ) };
 
 4577            pointPatternFillSl->setDistanceY( ( vYt + vYb ) + markerSize );
 
 4585        const double vYt { values.at( 0 ).toDouble( &ok ) };
 
 4588          const double vYb { values.at( 2 ).toDouble( &ok ) };
 
 4591            pointPatternFillSl->setDistanceY( ( vYt + vYb ) + markerSize );
 
 4594        const double vXr { values.at( 1 ).toDouble( &ok ) };
 
 4597          const double vXl { values.at( 3 ).toDouble( &ok ) };
 
 4600            pointPatternFillSl->setDistanceX( ( vXr + vXl ) + markerSize );
 
 4611  bool distanceFromVendorOption { 
false };
 
 4613  for ( QgsStringMap::iterator it = vendorOptions.begin(); it != vendorOptions.end(); ++it )
 
 4616    if ( it.key() == QLatin1String( 
"distance" ) )
 
 4618      distanceParser( it.value().split( 
',' ) );
 
 4619      distanceFromVendorOption = 
true;
 
 4622    else if ( it.key() == QLatin1String( 
"graphic-margin" ) )
 
 4624      distanceParser( it.value().split( 
' ' ) );
 
 4625      distanceFromVendorOption = 
true;
 
 4630  if ( ! distanceFromVendorOption && ! graphicFillElem.elementsByTagName( QStringLiteral( 
"Size" ) ).isEmpty() )
 
 4632    const QDomElement sizeElement { graphicFillElem.elementsByTagName( QStringLiteral( 
"Size" ) ).at( 0 ).toElement() };
 
 4634    const double size { sizeElement.text().toDouble( &ok ) };
 
 4637      pointPatternFillSl->setDistanceX( size );
 
 4638      pointPatternFillSl->setDistanceY( size );
 
 4642  return pointPatternFillSl.release();
 
 
 4724    attributes.unite( 
mMarkerSymbol->usedAttributes( context ) );
 
 
 4762  std::unique_ptr< QgsCentroidFillSymbolLayer > sl = std::make_unique< QgsCentroidFillSymbolLayer >();
 
 4764  if ( 
properties.contains( QStringLiteral( 
"point_on_surface" ) ) )
 
 4765    sl->setPointOnSurface( 
properties[QStringLiteral( 
"point_on_surface" )].toInt() != 0 );
 
 4766  if ( 
properties.contains( QStringLiteral( 
"point_on_all_parts" ) ) )
 
 4767    sl->setPointOnAllParts( 
properties[QStringLiteral( 
"point_on_all_parts" )].toInt() != 0 );
 
 4768  if ( 
properties.contains( QStringLiteral( 
"clip_points" ) ) )
 
 4769    sl->setClipPoints( 
properties[QStringLiteral( 
"clip_points" )].toInt() != 0 );
 
 4770  if ( 
properties.contains( QStringLiteral( 
"clip_on_current_part_only" ) ) )
 
 4771    sl->setClipOnCurrentPartOnly( 
properties[QStringLiteral( 
"clip_on_current_part_only" )].toInt() != 0 );
 
 4773  sl->restoreOldDataDefinedProperties( 
properties );
 
 4775  return sl.release();
 
 
 4780  return QStringLiteral( 
"CentroidFill" );
 
 
 4807  part.exterior = points;
 
 4809    part.rings = *rings;
 
 4817    mCurrentParts << part;
 
 4822    const double prevOpacity = 
mMarker->opacity();
 
 4826    mMarker->setOpacity( prevOpacity );
 
 
 4835  mCurrentParts.clear();
 
 
 4842  const double prevOpacity = 
mMarker->opacity();
 
 4848  mMarker->setOpacity( prevOpacity );
 
 
 4853void QgsCentroidFillSymbolLayer::render( 
QgsRenderContext &context, 
const QVector<QgsCentroidFillSymbolLayer::Part> &parts, 
const QgsFeature &feature, 
bool selected )
 
 4862  QVector< QgsGeometry > geometryParts;
 
 4863  geometryParts.reserve( parts.size() );
 
 4864  QPainterPath globalPath;
 
 4867  int maxAreaPartIdx = 0;
 
 4869  for ( 
int i = 0; i < parts.size(); i++ )
 
 4871    const Part part = parts[i];
 
 4874    if ( !geom.
isNull() && !part.rings.empty() )
 
 4876      QgsPolygon *poly = qgsgeometry_cast< QgsPolygon * >( geom.
get() );
 
 4880        int area = poly->
area();
 
 4882        if ( area > maxArea )
 
 4892      globalPath.addPolygon( part.exterior );
 
 4893      for ( 
const QPolygonF &ring : part.rings )
 
 4895        globalPath.addPolygon( ring );
 
 4900  for ( 
int i = 0; i < parts.size(); i++ )
 
 4905    const Part part = parts[i];
 
 4913        path.addPolygon( part.exterior );
 
 4914        for ( 
const QPolygonF &ring : part.rings )
 
 4916          path.addPolygon( ring );
 
 4925      context.
painter()->setClipPath( path );
 
 4932    mMarker->renderPoint( centroid, feature.
isValid() ? &feature : nullptr, context, -1, selected );
 
 4945  map[QStringLiteral( 
"point_on_surface" )] = QString::number( 
mPointOnSurface );
 
 4946  map[QStringLiteral( 
"point_on_all_parts" )] = QString::number( 
mPointOnAllParts );
 
 4947  map[QStringLiteral( 
"clip_points" )] = QString::number( 
mClipPoints );
 
 
 4954  std::unique_ptr< QgsCentroidFillSymbolLayer > x = std::make_unique< QgsCentroidFillSymbolLayer >();
 
 4957  x->setSubSymbol( 
mMarker->clone() );
 
 
 4972  mMarker->toSld( doc, element, props );
 
 
 4983  std::unique_ptr< QgsMarkerSymbol > marker( 
new QgsMarkerSymbol( layers ) );
 
 4985  std::unique_ptr< QgsCentroidFillSymbolLayer > sl = std::make_unique< QgsCentroidFillSymbolLayer >();
 
 4986  sl->setSubSymbol( marker.release() );
 
 4987  sl->setPointOnAllParts( 
false );
 
 4988  return sl.release();
 
 
 5015    attributes.unite( 
mMarker->usedAttributes( context ) );
 
 
 5038    mMarker->setOutputUnit( unit );
 
 
 5055    return mMarker->usesMapUnits();
 
 
 5064    mMarker->setMapUnitScale( scale );
 
 
 5072    return mMarker->mapUnitScale();
 
 
 5082  , mImageFilePath( imageFilePath )
 
 
 5099  if ( 
properties.contains( QStringLiteral( 
"imageFile" ) ) )
 
 5101    imagePath = 
properties[QStringLiteral( 
"imageFile" )].toString();
 
 5103  if ( 
properties.contains( QStringLiteral( 
"coordinate_mode" ) ) )
 
 5107  if ( 
properties.contains( QStringLiteral( 
"alpha" ) ) )
 
 5109    alpha = 
properties[QStringLiteral( 
"alpha" )].toDouble();
 
 5111  if ( 
properties.contains( QStringLiteral( 
"offset" ) ) )
 
 5115  if ( 
properties.contains( QStringLiteral( 
"angle" ) ) )
 
 5119  if ( 
properties.contains( QStringLiteral( 
"width" ) ) )
 
 5123  std::unique_ptr< QgsRasterFillSymbolLayer > symbolLayer = std::make_unique< QgsRasterFillSymbolLayer >( imagePath );
 
 5124  symbolLayer->setCoordinateMode( mode );
 
 5125  symbolLayer->setOpacity( alpha );
 
 5126  symbolLayer->setOffset( 
offset );
 
 5127  symbolLayer->setAngle( 
angle );
 
 5128  symbolLayer->setWidth( 
width );
 
 5129  if ( 
properties.contains( QStringLiteral( 
"offset_unit" ) ) )
 
 5133  if ( 
properties.contains( QStringLiteral( 
"offset_map_unit_scale" ) ) )
 
 5137  if ( 
properties.contains( QStringLiteral( 
"width_unit" ) ) )
 
 5141  if ( 
properties.contains( QStringLiteral( 
"width_map_unit_scale" ) ) )
 
 5146  if ( 
properties.contains( QStringLiteral( 
"height" ) ) )
 
 5148    symbolLayer->setHeight( 
properties[QStringLiteral( 
"height" )].toDouble() );
 
 5151  symbolLayer->restoreOldDataDefinedProperties( 
properties );
 
 5153  return symbolLayer.release();
 
 
 5158  QDomElement fillElem = element.firstChildElement( QStringLiteral( 
"Fill" ) );
 
 5159  if ( fillElem.isNull() )
 
 5162  QDomElement graphicFillElem = fillElem.firstChildElement( QStringLiteral( 
"GraphicFill" ) );
 
 5163  if ( graphicFillElem.isNull() )
 
 5166  QDomElement graphicElem = graphicFillElem.firstChildElement( QStringLiteral( 
"Graphic" ) );
 
 5167  if ( graphicElem.isNull() )
 
 5170  QString path, mimeType;
 
 5178  if ( ! QFile::exists( path ) )
 
 5183  std::unique_ptr< QgsRasterFillSymbolLayer> sl = std::make_unique< QgsRasterFillSymbolLayer>( path );
 
 5185  return sl.release();
 
 
 5190  QVariantMap::iterator it = 
properties.find( QStringLiteral( 
"imageFile" ) );
 
 5194      it.value() = pathResolver.
writePath( it.value().toString() );
 
 5196      it.value() = pathResolver.
readPath( it.value().toString() );
 
 
 5208  return QStringLiteral( 
"RasterFill" );
 
 
 5219  QPointF 
offset = mOffset;
 
 5237    QRectF boundingRect = points.boundingRect();
 
 5238    mBrush.setTransform( 
mBrush.transform().translate( boundingRect.left() - 
mBrush.transform().dx(),
 
 5239                         boundingRect.top() - 
mBrush.transform().dy() ) );
 
 
 5251  applyPattern( 
mBrush, mImageFilePath, mWidth, mHeight, mOpacity * context.
opacity(), context );
 
 
 5262  map[QStringLiteral( 
"imageFile" )] = mImageFilePath;
 
 5263  map[QStringLiteral( 
"coordinate_mode" )] = QString::number( 
static_cast< int >( mCoordinateMode ) );
 
 5264  map[QStringLiteral( 
"alpha" )] = QString::number( mOpacity );
 
 5268  map[QStringLiteral( 
"angle" )] = QString::number( 
mAngle );
 
 5270  map[QStringLiteral( 
"width" )] = QString::number( mWidth );
 
 5271  map[QStringLiteral( 
"height" )] = QString::number( mHeight );
 
 
 5280  std::unique_ptr< QgsRasterFillSymbolLayer > sl = std::make_unique< QgsRasterFillSymbolLayer >( mImageFilePath );
 
 5281  sl->setCoordinateMode( mCoordinateMode );
 
 5282  sl->setOpacity( mOpacity );
 
 5283  sl->setOffset( mOffset );
 
 5284  sl->setOffsetUnit( mOffsetUnit );
 
 5285  sl->setOffsetMapUnitScale( mOffsetMapUnitScale );
 
 5287  sl->setWidth( mWidth );
 
 5288  sl->setHeight( mHeight );
 
 5289  sl->setSizeUnit( mSizeUnit );
 
 5290  sl->setSizeMapUnitScale( mSizeMapUnitScale );
 
 5294  return sl.release();
 
 
 5299  return context.
convertToPainterUnits( std::max( std::fabs( mOffset.x() ), std::fabs( mOffset.y() ) ), mOffsetUnit, mOffsetMapUnitScale );
 
 
 5322  mImageFilePath = imagePath;
 
 
 5327  mCoordinateMode = mode;
 
 
 5346  if ( !hasWidthExpression && !hasHeightExpression && !hasAngleExpression && !hasOpacityExpression && !hasFileExpression )
 
 5352  if ( hasAngleExpression )
 
 5360  if ( !hasWidthExpression && !hasHeightExpression && !hasOpacityExpression && !hasFileExpression )
 
 5365  double width = mWidth;
 
 5366  if ( hasWidthExpression )
 
 5372  if ( hasHeightExpression )
 
 5378  if ( hasOpacityExpression )
 
 5383  QString file = mImageFilePath;
 
 5384  if ( hasFileExpression )
 
 
 5397void QgsRasterFillSymbolLayer::applyPattern( QBrush &brush, 
const QString &imageFilePath, 
const double width, 
const double height, 
const double alpha, 
const QgsSymbolRenderContext &context )
 
 5399  double imageWidth = 0;
 
 5400  double imageHeight = 0;
 
 5415      if ( originalSize.isEmpty() )
 
 5418      imageWidth = ( 
width * originalSize.width() ) / 100.0;
 
 5421      if ( 
static_cast< int >( imageWidth ) < 1 || 10000.0 < imageWidth )
 
 5434      if ( !originalSize.isValid() )
 
 5437      if ( originalSize.isEmpty() )
 
 5440      imageHeight = ( 
height * originalSize.height() ) / 100.0;
 
 5443      if ( 
static_cast< int >( imageHeight ) < 1 || 10000.0 < imageHeight )
 
 5448  if ( 
width == 0 && imageHeight > 0 )
 
 5450    if ( !originalSize.isValid() )
 
 5453    imageWidth = imageHeight * originalSize.width() / originalSize.height();
 
 5455  else if ( 
height == 0 && imageWidth > 0 )
 
 5457    if ( !originalSize.isValid() )
 
 5460    imageHeight = imageWidth * originalSize.height() / originalSize.width();
 
 5462  if ( imageWidth == 0 || imageHeight == 0 )
 
 5464    if ( !originalSize.isValid() )
 
 5467    imageWidth = originalSize.width();
 
 5468    imageHeight = originalSize.height();
 
 5476  brush.setTextureImage( img );
 
 5485  : mCountMethod( method )
 
 5486  , mPointCount( pointCount )
 
 5487  , mDensityArea( densityArea )
 
 
 5498  const int pointCount = 
properties.value( QStringLiteral( 
"point_count" ), QStringLiteral( 
"10" ) ).toInt();
 
 5499  const double densityArea = 
properties.value( QStringLiteral( 
"density_area" ), QStringLiteral( 
"250.0" ) ).toDouble();
 
 5501  unsigned long seed = 0;
 
 5502  if ( 
properties.contains( QStringLiteral( 
"seed" ) ) )
 
 5508    std::random_device rd;
 
 5509    std::mt19937 mt( 
seed == 0 ? rd() : 
seed );
 
 5510    std::uniform_int_distribution<> uniformDist( 1, 999999999 );
 
 5511    seed = uniformDist( mt );
 
 5516  if ( 
properties.contains( QStringLiteral( 
"density_area_unit" ) ) )
 
 5518  if ( 
properties.contains( QStringLiteral( 
"density_area_unit_scale" ) ) )
 
 5521  if ( 
properties.contains( QStringLiteral( 
"clip_points" ) ) )
 
 5523    sl->setClipPoints( 
properties[QStringLiteral( 
"clip_points" )].toInt() );
 
 5526  return sl.release();
 
 
 5531  return QStringLiteral( 
"RandomMarkerFill" );
 
 
 5536  mMarker->setColor( 
color );
 
 
 5542  return mMarker ? mMarker->color() : 
mColor;
 
 
 5558  part.exterior = points;
 
 5560    part.rings = *rings;
 
 5562  if ( mRenderingFeature )
 
 5566    mFeatureSymbolOpacity = context.
opacity();
 
 5567    mCurrentParts << part;
 
 5572    const double prevOpacity = mMarker->opacity();
 
 5573    mMarker->setOpacity( mMarker->opacity() * context.
opacity() );
 
 5576    mMarker->setOpacity( prevOpacity );
 
 
 5580void QgsRandomMarkerFillSymbolLayer::render( 
QgsRenderContext &context, 
const QVector<QgsRandomMarkerFillSymbolLayer::Part> &parts, 
const QgsFeature &feature, 
bool selected )
 
 5589  QVector< QgsGeometry > geometryParts;
 
 5590  geometryParts.reserve( parts.size() );
 
 5593  for ( 
const Part &part : parts )
 
 5596    if ( !geom.
isNull() && !part.rings.empty() )
 
 5598      QgsPolygon *poly = qgsgeometry_cast< QgsPolygon * >( geom.
get() );
 
 5599      for ( 
const QPolygonF &ring : part.rings )
 
 5606      geom = geom.
buffer( 0, 0 );
 
 5608    geometryParts << geom;
 
 5612      path.addPolygon( part.exterior );
 
 5613      for ( 
const QPolygonF &ring : part.rings )
 
 5615        path.addPolygon( ring );
 
 5625    context.
painter()->setClipPath( path );
 
 5629  int count = mPointCount;
 
 5636  switch ( mCountMethod )
 
 5648      count = std::max( 0.0, std::ceil( count * ( geom.
area() / 
densityArea ) ) );
 
 5655  unsigned long seed = mSeed;
 
 5666  std::sort( randomPoints.begin(), randomPoints.end(), []( 
const QgsPointXY & a, 
const QgsPointXY & b )->bool
 
 5668    return a.y() < b.y();
 
 5674  const bool needsExpressionContext = mMarker->hasDataDefinedProperties();
 
 5679  for ( 
const QgsPointXY &p : std::as_const( randomPoints ) )
 
 5681    if ( needsExpressionContext )
 
 5683    mMarker->renderPoint( QPointF( p.x(), p.y() ), feature.
isValid() ? &feature : nullptr, context, -1, selected );
 
 5697  map.insert( QStringLiteral( 
"count_method" ), QString::number( 
static_cast< int >( mCountMethod ) ) );
 
 5698  map.insert( QStringLiteral( 
"point_count" ), QString::number( mPointCount ) );
 
 5699  map.insert( QStringLiteral( 
"density_area" ), QString::number( mDensityArea ) );
 
 5702  map.insert( QStringLiteral( 
"seed" ), QString::number( mSeed ) );
 
 5703  map.insert( QStringLiteral( 
"clip_points" ), QString::number( mClipPoints ) );
 
 
 5709  std::unique_ptr< QgsRandomMarkerFillSymbolLayer > res = std::make_unique< QgsRandomMarkerFillSymbolLayer >( mPointCount, mCountMethod, mDensityArea, mSeed );
 
 5712  res->setDensityAreaUnit( mDensityAreaUnit );
 
 5713  res->setDensityAreaUnitScale( mDensityAreaUnitScale );
 
 5714  res->mClipPoints = mClipPoints;
 
 5715  res->setSubSymbol( mMarker->clone() );
 
 5718  return res.release();
 
 
 5728  return mMarker.get();
 
 
 5740  mColor = mMarker->color();
 
 
 5749    attributes.unite( mMarker->usedAttributes( context ) );
 
 
 5758  if ( mMarker && mMarker->hasDataDefinedProperties() )
 
 
 5795  return mCountMethod;
 
 
 5800  mCountMethod = method;
 
 
 5805  return mDensityArea;
 
 
 5810  mDensityArea = area;
 
 
 5817  mRenderingFeature = 
true;
 
 5818  mCurrentParts.clear();
 
 
 5823  mRenderingFeature = 
false;
 
 5825  const double prevOpacity = mMarker->opacity();
 
 5826  mMarker->setOpacity( mMarker->opacity() * mFeatureSymbolOpacity );
 
 5828  render( context, mCurrentParts, feature, 
false );
 
 5830  mFeatureSymbolOpacity = 1;
 
 5831  mMarker->setOpacity( prevOpacity );
 
 
 5839  mDensityAreaUnit = unit;
 
 5842    mMarker->setOutputUnit( unit );
 
 
 5850    return mMarker->outputUnit();
 
 
 5859    return mMarker->usesMapUnits();
 
 
 5868    mMarker->setMapUnitScale( scale );
 
 
 5876    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.
@ Absolute
The point count is used as an absolute count of markers.
@ DensityBased
The point count is part of a marker density count.
RenderUnit
Rendering size units.
@ Percentage
Percentage of another measurement (e.g., canvas size, feature size)
@ Unknown
Mixed or unknown units.
@ MetersInMapUnits
Meters value as Map units.
@ RenderingSubSymbol
Set whenever a sub-symbol of a parent symbol is currently being rendered. Can be used during symbol a...
@ RenderSymbolPreview
The render is for a symbol preview only and map based properties may not be available,...
@ RenderMapTile
Draw map such that there are no problems between adjacent tiles.
@ HighQualityImageTransforms
Enable high quality image transformations, which results in better appearance of scaled or rotated ra...
@ RenderBlocking
Render and load remote sources in the same thread to ensure rendering remote sources (svg and images)...
GradientType
Gradient types.
@ Conical
Conical (polar) gradient.
@ Radial
Radial (circular) gradient.
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.
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
void setMapUnitScale(const QgsMapUnitScale &scale) override
bool canCauseArtifactsBetweenAdjacentTiles() const override
Returns true if the symbol layer rendering can cause visible artifacts across a single feature when t...
bool pointOnSurface() const
QgsMapUnitScale mapUnitScale() const override
void startFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called before the layer will be rendered for a particular feature.
std::unique_ptr< QgsMarkerSymbol > mMarker
QString layerType() const override
Returns a string that represents this layer type.
void setColor(const QColor &color) override
Sets the "representative" color for the symbol layer.
bool pointOnAllParts() const
Returns whether a point is drawn for all parts or only on the biggest part of multi-part features.
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
bool hasDataDefinedProperties() const override
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
bool setSubSymbol(QgsSymbol *symbol) FINAL
Sets layer's subsymbol. takes ownership of the passed symbol.
void stopFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called after the layer has been rendered for a particular feature.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
bool clipPoints() const
Returns true if point markers should be clipped to the polygon boundary.
QgsCentroidFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
void toSld(QDomDocument &doc, QDomElement &element, const QVariantMap &props) const override
Saves the symbol layer as SLD.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsCentroidFillSymbolLayer using the specified properties map containing symbol propert...
~QgsCentroidFillSymbolLayer() override
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
double mFeatureSymbolOpacity
QgsCentroidFillSymbolLayer()
QColor color() const override
Returns the "representative" color of the symbol layer.
bool clipOnCurrentPartOnly() const
Returns true if point markers should be clipped to the current part boundary only.
bool mClipOnCurrentPartOnly
Abstract base class for color ramps.
virtual QColor color(double value) const =0
Returns the color corresponding to a specified value.
virtual QVariantMap properties() const =0
Returns a string map containing all the color ramp's properties.
virtual QgsColorRamp * clone() const =0
Creates a clone of the color ramp.
virtual QString type() const =0
Returns a string representing the color ramp type.
static QColor colorFromString(const QString &string)
Decodes a string into a color value.
static QString colorToString(const QColor &color)
Encodes a color into a string value.
static QgsColorRamp * create(const QVariantMap &properties=QVariantMap())
Creates the symbol layer.
static QString typeString()
Returns the string identifier for QgsCptCityColorRamp.
double area() const override
Returns the planar, 2-dimensional area of the geometry.
Exports QGIS layers to the DXF format.
static double mapUnitScaleFactor(double scale, Qgis::RenderUnit symbolUnits, Qgis::DistanceUnit mapUnits, double mapUnitsPerPixel=1.0)
Returns scale factor for conversion to map units.
Qgis::DistanceUnit mapUnits() const
Retrieve map units.
double symbologyScale() const
Returns the reference scale for output.
RAII class to pop scope from an expression context on destruction.
Single scope for storing variables and functions for use within a QgsExpressionContext.
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
static const QString EXPR_GEOMETRY_POINT_NUM
Inbuilt variable name for point number variable.
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for the context.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
bool isValid() const
Returns the validity of this feature.
bool isCanceled() const
Tells whether the operation has been canceled already.
static QString uniquePath(const QString &path)
Creates a unique file path name from a desired path by appending "_<n>" (where "<n>" is an integer 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...
static QgsGeometry fromRect(const QgsRectangle &rect)
Creates a new geometry from a QgsRectangle.
static QgsGeometry fromQPolygonF(const QPolygonF &polygon)
Construct geometry from a QPolygonF.
QgsAbstractGeometry * get()
Returns a modifiable (non-const) reference to the underlying abstract geometry primitive.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
bool contains(const QgsPointXY *p) const
Returns true if the geometry contains the point p.
bool isGeosValid(Qgis::GeometryValidityFlags flags=Qgis::GeometryValidityFlags()) const
Checks validity of the geometry using GEOS.
double area() const
Returns the planar, 2-dimensional area of the geometry.
QgsGeometry buffer(double distance, int segments) const
Returns a buffer region around this geometry having the given width and with a specified number of se...
static QgsGeometry unaryUnion(const QVector< QgsGeometry > &geometries, const QgsGeometryParameters ¶meters=QgsGeometryParameters())
Compute the unary union on a list of geometries.
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometry *geometry, double precision=0.0)
Creates and returns a new geometry engine representing the specified geometry using precision on a gr...
Gradient color ramp, which smoothly interpolates between two colors and also supports optional extra ...
static QgsColorRamp * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsColorRamp from a map of properties.
static QString typeString()
Returns the string identifier for QgsGradientColorRamp.
void addStopsToGradient(QGradient *gradient, double opacity=1) const
Copy color ramp stops to a QGradient.
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)
bool mMarkerSymbolRenderStarted
A class to represent a 2D point.
Point geometry type, with support for z-dimension and m-values.
void addInteriorRing(QgsCurve *ring) override
Adds an interior ring to the geometry (takes ownership)
static QgsProject * instance()
Returns the QgsProject singleton instance.
QgsPathResolver pathResolver() const
Returns path resolver object with considering whether the project uses absolute or relative paths and...
QVariant value(int key, const QgsExpressionContext &context, const QVariant &defaultValue=QVariant()) const final
Returns the calculated value of the property with the specified key from within the collection.
bool isActive(int key) const final
Returns true if the collection contains an active property with the specified key.
static QVariantMap propertyMapToVariantMap(const QMap< QString, QgsProperty > &propertyMap)
Convert a map of QgsProperty to a map of QVariant This is useful to save a map of properties.
static QMap< QString, QgsProperty > variantMapToPropertyMap(const QVariantMap &variantMap)
Convert a map of QVariant to a map of QgsProperty This is useful to restore a map of properties.
A fill symbol layer which places markers at random locations within polygons.
~QgsRandomMarkerFillSymbolLayer() override
int pointCount() const
Returns the count of random points to render in the fill.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
void startFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called before the layer will be rendered for a particular feature.
QgsRandomMarkerFillSymbolLayer(int pointCount=10, Qgis::PointCountMethod method=Qgis::PointCountMethod::Absolute, double densityArea=250.0, unsigned long seed=0)
Constructor for QgsRandomMarkerFillSymbolLayer, with the specified pointCount.
unsigned long seed() const
Returns the random number seed to use when generating points, or 0 if a truly random sequence will be...
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsRandomMarkerFillSymbolLayer using the specified properties map containing symbol pro...
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
QString layerType() const override
Returns a string that represents this layer type.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
QgsRandomMarkerFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
void setMapUnitScale(const QgsMapUnitScale &scale) override
bool hasDataDefinedProperties() const override
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
void stopFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called after the layer has been rendered for a particular feature.
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
void setCountMethod(Qgis::PointCountMethod method)
Sets the count method used to randomly fill the polygon.
bool clipPoints() const
Returns true if point markers should be clipped to the polygon boundary.
bool canCauseArtifactsBetweenAdjacentTiles() const override
Returns true if the symbol layer rendering can cause visible artifacts across a single feature when t...
void setClipPoints(bool clipped)
Sets whether point markers should be clipped to the polygon boundary.
QgsSymbol * subSymbol() override
Returns the symbol's sub symbol, if present.
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
QColor color() const override
Returns the "representative" color of the symbol layer.
void setSeed(unsigned long seed)
Sets the random number seed to use when generating points, or 0 if a truly random sequence will be us...
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
void setPointCount(int count)
Sets the count of random points to render in the fill.
Qgis::PointCountMethod countMethod() const
Returns the count method used to randomly fill the polygon.
double densityArea() const
Returns the density area used to count the number of points to randomly fill the polygon.
void setColor(const QColor &color) override
Sets the "representative" color for the symbol layer.
bool setSubSymbol(QgsSymbol *symbol) FINAL
Sets layer's subsymbol. takes ownership of the passed symbol.
void setDensityArea(double area)
Sets the density area used to count the number of points to randomly fill the polygon.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QgsMapUnitScale mapUnitScale() const override
A class for filling symbols with a repeated raster image.
void applyDataDefinedSettings(QgsSymbolRenderContext &context) override
Applies data defined settings prior to generating the fill symbol brush.
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
double width() const
Returns the width used for scaling the image used in the fill.
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
static QgsSymbolLayer * createFromSld(QDomElement &element)
Creates a new QgsRasterFillSymbolLayer from a SLD element.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsRasterFillSymbolLayer from a properties map.
QString layerType() const override
Returns a string that represents this layer type.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QgsRasterFillSymbolLayer(const QString &imageFilePath=QString())
Constructor for QgsRasterFillSymbolLayer, using a raster fill from the specified imageFilePath.
double opacity() const
Returns the opacity for the raster image used in the fill.
~QgsRasterFillSymbolLayer() override
void setOpacity(double opacity)
Sets the opacity for the raster image used in the fill.
QColor color() const override
Returns the "representative" color of the symbol layer.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
QString imageFilePath() const
The path to the raster image used for the fill.
void setImageFilePath(const QString &imagePath)
Sets the path to the raster image used for the fill.
double height() const
Returns the height used for scaling the image used in the fill.
static void resolvePaths(QVariantMap &properties, const QgsPathResolver &pathResolver, bool saving)
Turns relative paths in properties map to absolute when reading and vice versa when writing.
QPointF offset() const
Returns the offset for the fill.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer's subsymbol. takes ownership of the passed symbol.
QgsRasterFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
bool applyBrushTransformFromContext(QgsSymbolRenderContext *context=nullptr) const override
Returns true if the image brush should be transformed using the render context's texture origin.
void setCoordinateMode(Qgis::SymbolCoordinateReference mode)
Set the coordinate mode for fill.
A rectangle specified with double values.
QgsPointXY center() const
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 QPointF polygonCentroid(const QPolygonF &points)
Calculate the centroid point of a QPolygonF.
static QString encodeBrushStyle(Qt::BrushStyle style)
static QString svgSymbolPathToName(const QString &path, const QgsPathResolver &pathResolver)
Determines an SVG symbol's name from its path.
static void externalGraphicToSld(QDomDocument &doc, QDomElement &element, const QString &path, const QString &mime, const QColor &color, double size=-1)
static QPointF polygonPointOnSurface(const QPolygonF &points, const QVector< QPolygonF > *rings=nullptr)
Calculate a point on the surface of a QPolygonF.
static QPointF toPoint(const QVariant &value, bool *ok=nullptr)
Converts a value to a point.
static void multiplyImageOpacity(QImage *image, qreal opacity)
Multiplies opacity of image pixel values with a (global) transparency value.
static QgsMapUnitScale decodeMapUnitScale(const QString &str)
static double rescaleUom(double size, Qgis::RenderUnit unit, const QVariantMap &props)
Rescales the given size based on the uomScale found in the props, if any is found,...
static QString ogrFeatureStylePen(double width, double mmScaleFactor, double mapUnitsScaleFactor, const QColor &c, Qt::PenJoinStyle joinStyle=Qt::MiterJoin, Qt::PenCapStyle capStyle=Qt::FlatCap, double offset=0.0, const QVector< qreal > *dashPattern=nullptr)
Create ogr feature style string for pen.
static bool externalGraphicFromSld(QDomElement &element, QString &path, QString &mime, QColor &color, double &size)
static void parametricSvgToSld(QDomDocument &doc, QDomElement &graphicElem, const QString &path, const QColor &fillColor, double size, const QColor &strokeColor, double strokeWidth)
Encodes a reference to a parametric SVG into SLD, as a succession of parametric SVG using URL paramet...
static bool lineFromSld(QDomElement &element, Qt::PenStyle &penStyle, QColor &color, double &width, Qt::PenJoinStyle *penJoinStyle=nullptr, Qt::PenCapStyle *penCapStyle=nullptr, QVector< qreal > *customDashPattern=nullptr, double *dashOffset=nullptr)
static QString ogrFeatureStyleBrush(const QColor &fillColr)
Create ogr feature style string for brush.
static QString encodeLineClipMode(Qgis::LineClipMode mode)
Encodes a line clip mode to a string.
static Qgis::LineClipMode decodeLineClipMode(const QString &string, bool *ok=nullptr)
Decodes a string representing a line clip mode.
static QPointF pointOnLineWithDistance(QPointF startPoint, QPointF directionPoint, double distance)
Returns a point on the line from startPoint to directionPoint that is a certain distance away from th...
static QSize tileSize(int width, int height, double &angleRad)
Calculate the minimum size in pixels of a symbol tile given the symbol width and height and the symbo...
static Qt::BrushStyle decodeBrushStyle(const QString &str)
static void lineToSld(QDomDocument &doc, QDomElement &element, Qt::PenStyle penStyle, const QColor &color, double width=-1, const Qt::PenJoinStyle *penJoinStyle=nullptr, const Qt::PenCapStyle *penCapStyle=nullptr, const QVector< qreal > *customDashPattern=nullptr, double dashOffset=0.0)
static QDomElement createVendorOptionElement(QDomDocument &doc, const QString &name, const QString &value)
static bool wellKnownMarkerFromSld(QDomElement &element, QString &name, QColor &color, QColor &strokeColor, Qt::PenStyle &strokeStyle, double &strokeWidth, double &size)
static void createDisplacementElement(QDomDocument &doc, QDomElement &element, QPointF offset)
static QString svgSymbolNameToPath(const QString &name, const QgsPathResolver &pathResolver)
Determines an SVG symbol's path from its name.
static QString encodeColor(const QColor &color)
static bool fillFromSld(QDomElement &element, Qt::BrushStyle &brushStyle, QColor &color)
static void fillToSld(QDomDocument &doc, QDomElement &element, Qt::BrushStyle brushStyle, const QColor &color=QColor())
static Qgis::RenderUnit decodeSldUom(const QString &str, double *scaleFactor=nullptr)
Decodes a SLD unit of measure string to a render unit.
static void createGeometryElement(QDomDocument &doc, QDomElement &element, const QString &geomFunc)
static double estimateMaxSymbolBleed(QgsSymbol *symbol, const QgsRenderContext &context)
Returns the maximum estimated bleed for the symbol.
static void wellKnownMarkerToSld(QDomDocument &doc, QDomElement &element, const QString &name, const QColor &color, const QColor &strokeColor, Qt::PenStyle strokeStyle, double strokeWidth=-1, double size=-1)
static Qt::PenStyle decodePenStyle(const QString &str)
static void createRotationElement(QDomDocument &doc, QDomElement &element, const QString &rotationFunc)
static Qgis::SymbolCoordinateReference decodeCoordinateReference(const QString &string, bool *ok=nullptr)
Decodes a string representing a symbol coordinate reference mode.
static QString encodePoint(QPointF point)
Encodes a QPointF to a string.
static QgsSymbolLayer * createMarkerLayerFromSld(QDomElement &element)
static QString encodePenJoinStyle(Qt::PenJoinStyle style)
static QgsStringMap getVendorOptionList(QDomElement &element)
static QPointF decodePoint(const QString &string)
Decodes a QSizeF from a string.
static QgsSymbolLayer * createLineLayerFromSld(QDomElement &element)
static QString encodeCoordinateReference(Qgis::SymbolCoordinateReference coordinateReference)
Encodes a symbol coordinate reference mode to a string.
static QString encodeMarkerClipMode(Qgis::MarkerClipMode mode)
Encodes a marker clip mode to a string.
virtual bool setSubSymbol(QgsSymbol *symbol)
Sets layer's subsymbol. takes ownership of the passed symbol.
bool shouldRenderUsingSelectionColor(const QgsSymbolRenderContext &context) const
Returns true if the symbol layer should be rendered using the selection color from the render context...
Qgis::SymbolType type() const
virtual QColor fillColor() const
Returns the fill color for the symbol layer.
static const bool SELECTION_IS_OPAQUE
Whether styles for selected features ignore symbol alpha.
void removeMasks(QgsRenderContext &context, bool recursive)
When rendering, remove previously installed masks from context painter if recursive is true masks are...
virtual QSet< QString > usedAttributes(const QgsRenderContext &context) const
Returns the set of attributes referenced by the layer.
void copyDataDefinedProperties(QgsSymbolLayer *destLayer) const
Copies all data defined properties of this layer to another symbol layer.
@ GradientType
Gradient fill type.
@ SecondaryColor
Secondary color (eg for gradient fills)
@ File
Filename, eg for svg files.
@ GradientReference2Y
Gradient reference point 2 y.
@ GradientReference1X
Gradient reference point 1 x.
@ OffsetY
Vertical offset.
@ OffsetX
Horizontal offset.
@ GradientReference1Y
Gradient reference point 1 y.
@ GradientSpread
Gradient spread mode.
@ ShapeburstMaxDistance
Shapeburst fill from edge distance.
@ StrokeStyle
Stroke style (eg solid, dashed)
@ DistanceY
Vertical distance between points.
@ DensityArea
Density area.
@ ClipPoints
Whether markers should be clipped to polygon boundaries.
@ LineClipping
Line clipping mode (since QGIS 3.24)
@ ShapeburstIgnoreRings
Shapeburst ignore rings.
@ ShapeburstUseWholeShape
Shapeburst use whole shape.
@ DisplacementX
Horizontal displacement.
@ CoordinateMode
Gradient coordinate mode.
@ FillStyle
Fill style (eg solid, dots)
@ GradientReference2X
Gradient reference point 2 x.
@ StrokeColor
Stroke color.
@ BlurRadius
Shapeburst blur radius.
@ MarkerClipping
Marker clipping mode (since QGIS 3.24)
@ RandomSeed
Random number seed.
@ LineAngle
Line angle, or angle of hash lines for hash line symbols.
@ JoinStyle
Line join style.
@ RandomOffsetY
Random offset Y (since QGIS 3.24)
@ DisplacementY
Vertical displacement.
@ DistanceX
Horizontal distance between points.
@ GradientReference1IsCentroid
Gradient reference point 1 is centroid.
@ StrokeWidth
Stroke width.
@ GradientReference2IsCentroid
Gradient reference point 2 is centroid.
@ LineDistance
Distance between lines, or length of lines for hash line symbols.
@ RandomOffsetX
Random offset X (since QGIS 3.24)
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.
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.
QColor color() const
Returns the symbol's color.
Qgis::SymbolType type() const
Returns the symbol's type.
double interval() const
Returns the interval between individual symbols.
const QgsMapUnitScale & intervalMapUnitScale() const
Returns the map unit scale for the interval between symbols.
void setInterval(double interval)
Sets the interval between individual symbols.
Qgis::RenderUnit intervalUnit() const
Returns the units for the interval between symbols.
static Q_INVOKABLE Qgis::RenderUnit decodeRenderUnit(const QString &string, bool *ok=nullptr)
Decodes a render unit from a string.
static Q_INVOKABLE QString encodeUnit(Qgis::DistanceUnit unit)
Encodes a distance unit to a string.
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
QMap< QString, QString > QgsStringMap
#define DEFAULT_SIMPLEFILL_JOINSTYLE
#define DEFAULT_SIMPLEFILL_COLOR
#define DEFAULT_SIMPLEFILL_STYLE
#define DEFAULT_SIMPLEFILL_BORDERSTYLE
#define DEFAULT_SIMPLEFILL_BORDERCOLOR
#define DEFAULT_SIMPLEFILL_BORDERWIDTH
QList< QgsSymbolLayer * > QgsSymbolLayerList
Single variable definition for use within a QgsExpressionContextScope.