36 #include <QSvgRenderer> 37 #include <QDomDocument> 38 #include <QDomElement> 41 Qt::PenJoinStyle penJoinStyle )
42 : mBrushStyle( style )
43 , mStrokeColor( strokeColor )
44 , mStrokeStyle( strokeStyle )
45 , mStrokeWidth( strokeWidth )
46 , mPenJoinStyle( penJoinStyle )
82 void QgsSimpleFillSymbolLayer::applyDataDefinedSymbology(
QgsSymbolRenderContext &context, QBrush &brush, QPen &pen, QPen &selPen )
98 if ( exprVal.isValid() )
110 double width = exprVal.toDouble( &ok );
114 pen.setWidthF( width );
115 selPen.setWidthF( width );
151 if ( props.contains( QStringLiteral(
"color" ) ) )
153 if ( props.contains( QStringLiteral(
"style" ) ) )
155 if ( props.contains( QStringLiteral(
"color_border" ) ) )
160 else if ( props.contains( QStringLiteral(
"outline_color" ) ) )
164 else if ( props.contains( QStringLiteral(
"line_color" ) ) )
169 if ( props.contains( QStringLiteral(
"style_border" ) ) )
174 else if ( props.contains( QStringLiteral(
"outline_style" ) ) )
178 else if ( props.contains( QStringLiteral(
"line_style" ) ) )
182 if ( props.contains( QStringLiteral(
"width_border" ) ) )
185 strokeWidth = props[QStringLiteral(
"width_border" )].toDouble();
187 else if ( props.contains( QStringLiteral(
"outline_width" ) ) )
189 strokeWidth = props[QStringLiteral(
"outline_width" )].toDouble();
191 else if ( props.contains( QStringLiteral(
"line_width" ) ) )
193 strokeWidth = props[QStringLiteral(
"line_width" )].toDouble();
195 if ( props.contains( QStringLiteral(
"offset" ) ) )
197 if ( props.contains( QStringLiteral(
"joinstyle" ) ) )
201 sl->setOffset( offset );
202 if ( props.contains( QStringLiteral(
"border_width_unit" ) ) )
206 else if ( props.contains( QStringLiteral(
"outline_width_unit" ) ) )
210 else if ( props.contains( QStringLiteral(
"line_width_unit" ) ) )
214 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
217 if ( props.contains( QStringLiteral(
"border_width_map_unit_scale" ) ) )
219 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
222 sl->restoreOldDataDefinedProperties( props );
230 return QStringLiteral(
"SimpleFill" );
250 mPen = QPen( strokeColor );
280 p->translate( offset );
287 p->translate( -offset );
298 map[QStringLiteral(
"outline_width" )] = QString::number(
mStrokeWidth );
326 QDomElement symbolizerElem = doc.createElement( QStringLiteral(
"se:PolygonSymbolizer" ) );
327 if ( !props.value( QStringLiteral(
"uom" ), QString() ).isEmpty() )
328 symbolizerElem.setAttribute( QStringLiteral(
"uom" ), props.value( QStringLiteral(
"uom" ), QString() ) );
329 element.appendChild( symbolizerElem );
337 QDomElement fillElem = doc.createElement( QStringLiteral(
"se:Fill" ) );
338 symbolizerElem.appendChild( fillElem );
345 QDomElement strokeElem = doc.createElement( QStringLiteral(
"se:Stroke" ) );
346 symbolizerElem.appendChild( strokeElem );
361 symbolStyle.append(
';' );
370 Qt::BrushStyle fillStyle;
374 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
377 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
383 QString uom = element.attribute( QStringLiteral(
"uom" ), QString() );
389 sl->setOutputUnit( QgsUnitTypes::RenderUnit::RenderPixels );
390 sl->setOffset( offset );
398 return penBleed + offsetBleed;
459 : mGradientColorType( colorType )
460 , mGradientType( gradientType )
461 , mCoordinateMode( coordinateMode )
462 , mGradientSpread( spread )
463 , mReferencePoint1( QPointF( 0.5, 0 ) )
464 , mReferencePoint2( QPointF( 0.5, 1 ) )
485 bool refPoint1IsCentroid =
false;
487 bool refPoint2IsCentroid =
false;
492 if ( props.contains( QStringLiteral(
"type" ) ) )
493 type = static_cast< GradientType >( props[QStringLiteral(
"type" )].toInt() );
494 if ( props.contains( QStringLiteral(
"coordinate_mode" ) ) )
495 coordinateMode = static_cast< GradientCoordinateMode >( props[QStringLiteral(
"coordinate_mode" )].toInt() );
496 if ( props.contains( QStringLiteral(
"spread" ) ) )
497 gradientSpread = static_cast< GradientSpread >( props[QStringLiteral(
"spread" )].toInt() );
498 if ( props.contains( QStringLiteral(
"color_type" ) ) )
499 colorType = static_cast< GradientColorType >( props[QStringLiteral(
"color_type" )].toInt() );
500 if ( props.contains( QStringLiteral(
"gradient_color" ) ) )
505 else if ( props.contains( QStringLiteral(
"color" ) ) )
509 if ( props.contains( QStringLiteral(
"gradient_color2" ) ) )
514 if ( props.contains( QStringLiteral(
"reference_point1" ) ) )
516 if ( props.contains( QStringLiteral(
"reference_point1_iscentroid" ) ) )
517 refPoint1IsCentroid = props[QStringLiteral(
"reference_point1_iscentroid" )].toInt();
518 if ( props.contains( QStringLiteral(
"reference_point2" ) ) )
520 if ( props.contains( QStringLiteral(
"reference_point2_iscentroid" ) ) )
521 refPoint2IsCentroid = props[QStringLiteral(
"reference_point2_iscentroid" )].toInt();
522 if ( props.contains( QStringLiteral(
"angle" ) ) )
523 angle = props[QStringLiteral(
"angle" )].toDouble();
525 if ( props.contains( QStringLiteral(
"offset" ) ) )
530 if ( props.contains( QStringLiteral(
"rampType" ) ) && props[QStringLiteral(
"rampType" )] == QStringLiteral(
"cpt-city" ) )
541 sl->setOffset( offset );
542 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
544 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
546 sl->setReferencePoint1( referencePoint1 );
547 sl->setReferencePoint1IsCentroid( refPoint1IsCentroid );
548 sl->setReferencePoint2( referencePoint2 );
549 sl->setReferencePoint2IsCentroid( refPoint2IsCentroid );
550 sl->setAngle( angle );
552 sl->setColorRamp( gradientRamp );
554 sl->restoreOldDataDefinedProperties( props );
567 return QStringLiteral(
"GradientFill" );
570 void QgsGradientFillSymbolLayer::applyDataDefinedSymbology(
QgsSymbolRenderContext &context,
const QPolygonF &points )
613 if ( currentType == QObject::tr(
"linear" ) )
617 else if ( currentType == QObject::tr(
"radial" ) )
621 else if ( currentType == QObject::tr(
"conical" ) )
635 if ( currentCoordMode == QObject::tr(
"feature" ) )
639 else if ( currentCoordMode == QObject::tr(
"viewport" ) )
653 if ( currentSpread == QObject::tr(
"pad" ) )
657 else if ( currentSpread == QObject::tr(
"repeat" ) )
661 else if ( currentSpread == QObject::tr(
"reflect" ) )
708 if ( refPoint1IsCentroid || refPoint2IsCentroid )
713 QRectF bbox = points.boundingRect();
714 double centroidX = ( centroid.x() - bbox.left() ) / bbox.width();
715 double centroidY = ( centroid.y() - bbox.top() ) / bbox.height();
717 if ( refPoint1IsCentroid )
719 refPoint1X = centroidX;
720 refPoint1Y = centroidY;
722 if ( refPoint2IsCentroid )
724 refPoint2X = centroidX;
725 refPoint2Y = centroidY;
731 spread, QPointF( refPoint1X, refPoint1Y ), QPointF( refPoint2X, refPoint2Y ), angle );
734 QPointF QgsGradientFillSymbolLayer::rotateReferencePoint( QPointF refPoint,
double angle )
739 QLineF refLine = QLineF( QPointF( 0.5, 0.5 ), refPoint );
741 refLine.setAngle( refLine.angle() +
angle );
743 QPointF rotatedReferencePoint = refLine.p2();
745 if ( rotatedReferencePoint.x() > 1 )
746 rotatedReferencePoint.setX( 1 );
747 if ( rotatedReferencePoint.x() < 0 )
748 rotatedReferencePoint.setX( 0 );
749 if ( rotatedReferencePoint.y() > 1 )
750 rotatedReferencePoint.setY( 1 );
751 if ( rotatedReferencePoint.y() < 0 )
752 rotatedReferencePoint.setY( 0 );
754 return rotatedReferencePoint;
765 fillColor.setAlphaF( context.
opacity() * fillColor.alphaF() );
766 QColor fillColor2 =
color2;
767 fillColor2.setAlphaF( context.
opacity() * fillColor2.alphaF() );
778 gradient = QLinearGradient( rotatedReferencePoint1, rotatedReferencePoint2 );
781 gradient = QRadialGradient( rotatedReferencePoint1, QLineF( rotatedReferencePoint1, rotatedReferencePoint2 ).length() );
784 gradient = QConicalGradient( rotatedReferencePoint1, QLineF( rotatedReferencePoint1, rotatedReferencePoint2 ).
angle() );
790 gradient.setCoordinateMode( QGradient::ObjectBoundingMode );
793 gradient.setCoordinateMode( QGradient::StretchToDeviceMode );
799 gradient.setSpread( QGradient::PadSpread );
802 gradient.setSpread( QGradient::ReflectSpread );
805 gradient.setSpread( QGradient::RepeatSpread );
811 ( gradientRamp->
type() == QLatin1String(
"gradient" ) || gradientRamp->
type() == QLatin1String(
"cpt-city" ) ) )
820 gradient.setColorAt( 0.0, fillColor );
821 gradient.setColorAt( 1.0, fillColor2 );
825 brush = QBrush( gradient );
832 selColor.setAlphaF( context.
opacity() );
849 applyDataDefinedSymbology( context, points );
852 p->setPen( Qt::NoPen );
859 p->translate( offset );
866 p->translate( -offset );
876 map[QStringLiteral(
"type" )] = QString::number(
mGradientType );
877 map[QStringLiteral(
"coordinate_mode" )] = QString::number(
mCoordinateMode );
883 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
941 int blurRadius,
bool useWholeShape,
double maxDistance )
942 : mBlurRadius( blurRadius )
943 , mUseWholeShape( useWholeShape )
944 , mMaxDistance( maxDistance )
945 , mColorType( colorType )
964 if ( props.contains( QStringLiteral(
"color_type" ) ) )
966 colorType =
static_cast< ShapeburstColorType >( props[QStringLiteral(
"color_type" )].toInt() );
968 if ( props.contains( QStringLiteral(
"shapeburst_color" ) ) )
973 else if ( props.contains( QStringLiteral(
"color" ) ) )
978 if ( props.contains( QStringLiteral(
"shapeburst_color2" ) ) )
983 else if ( props.contains( QStringLiteral(
"gradient_color2" ) ) )
987 if ( props.contains( QStringLiteral(
"blur_radius" ) ) )
989 blurRadius = props[QStringLiteral(
"blur_radius" )].toInt();
991 if ( props.contains( QStringLiteral(
"use_whole_shape" ) ) )
993 useWholeShape = props[QStringLiteral(
"use_whole_shape" )].toInt();
995 if ( props.contains( QStringLiteral(
"max_distance" ) ) )
997 maxDistance = props[QStringLiteral(
"max_distance" )].toDouble();
999 if ( props.contains( QStringLiteral(
"offset" ) ) )
1006 if ( props.contains( QStringLiteral(
"rampType" ) ) && props[QStringLiteral(
"rampType" )] == QStringLiteral(
"cpt-city" ) )
1017 sl->setOffset( offset );
1018 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
1022 if ( props.contains( QStringLiteral(
"distance_unit" ) ) )
1026 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
1030 if ( props.contains( QStringLiteral(
"distance_map_unit_scale" ) ) )
1034 if ( props.contains( QStringLiteral(
"ignore_rings" ) ) )
1036 sl->setIgnoreRings( props[QStringLiteral(
"ignore_rings" )].toInt() );
1040 sl->setColorRamp( gradientRamp );
1043 sl->restoreOldDataDefinedProperties( props );
1045 return sl.release();
1050 return QStringLiteral(
"ShapeburstFill" );
1055 if ( mGradientRamp.get() == ramp )
1058 mGradientRamp.reset( ramp );
1105 ignoreRings = mIgnoreRings;
1119 selColor.setAlphaF( context.
opacity() );
1120 mSelBrush = QBrush( selColor );
1125 Q_UNUSED( context );
1139 p->setBrush( mSelBrush );
1141 if ( !mOffset.isNull() )
1145 p->translate( offset );
1148 if ( !mOffset.isNull() )
1150 p->translate( -offset );
1161 applyDataDefinedSymbology( context, color1, color2, blurRadius, useWholeShape, maxDistance, ignoreRings );
1164 int outputPixelMaxDist = 0;
1172 std::unique_ptr< QgsGradientColorRamp > twoColorGradientRamp;
1175 twoColorGradientRamp = qgis::make_unique< QgsGradientColorRamp >( color1,
color2 );
1179 p->setPen( QPen( Qt::NoPen ) );
1182 int sideBuffer = 4 + ( blurRadius + 2 ) * 4;
1184 int pointsWidth =
static_cast< int >( std::round( points.boundingRect().width() ) );
1185 int pointsHeight =
static_cast< int >( std::round( points.boundingRect().height() ) );
1186 int imWidth = pointsWidth + ( sideBuffer * 2 );
1187 int imHeight = pointsHeight + ( sideBuffer * 2 );
1188 std::unique_ptr< QImage > fillImage = qgis::make_unique< QImage >( imWidth,
1189 imHeight, QImage::Format_ARGB32_Premultiplied );
1190 if ( fillImage->isNull() )
1197 std::unique_ptr< QImage > alphaImage = qgis::make_unique< QImage >( fillImage->width(), fillImage->height(), QImage::Format_ARGB32_Premultiplied );
1198 if ( alphaImage->isNull() )
1207 fillImage->fill( Qt::black );
1210 alphaImage->fill( Qt::transparent );
1213 QPainter imgPainter;
1214 imgPainter.begin( alphaImage.get() );
1215 imgPainter.setRenderHint( QPainter::Antialiasing,
true );
1216 imgPainter.setBrush( QBrush( Qt::white ) );
1217 imgPainter.setPen( QPen( Qt::black ) );
1218 imgPainter.translate( -points.boundingRect().left() + sideBuffer, - points.boundingRect().top() + sideBuffer );
1224 imgPainter.begin( fillImage.get() );
1227 imgPainter.drawImage( 0, 0, *alphaImage );
1234 imgPainter.setBrush( QBrush( Qt::white ) );
1235 imgPainter.setPen( QPen( Qt::black ) );
1236 imgPainter.translate( -points.boundingRect().left() + sideBuffer, - points.boundingRect().top() + sideBuffer );
1242 double *dtArray = distanceTransform( fillImage.get() );
1252 if ( blurRadius > 0 )
1258 imgPainter.begin( fillImage.get() );
1259 imgPainter.setCompositionMode( QPainter::CompositionMode_DestinationIn );
1260 imgPainter.drawImage( 0, 0, *alphaImage );
1269 if ( !mOffset.isNull() )
1273 p->translate( offset );
1276 p->drawImage( points.boundingRect().left() - sideBuffer, points.boundingRect().top() - sideBuffer, *fillImage );
1278 if ( !mOffset.isNull() )
1280 p->translate( -offset );
1289 void QgsShapeburstFillSymbolLayer::distanceTransform1d(
double *f,
int n,
int *v,
double *z,
double *d )
1295 for (
int q = 1; q <= n - 1; q++ )
1297 double s = ( ( f[q] + q * q ) - ( f[v[k]] + ( v[k] * v[k] ) ) ) / ( 2 * q - 2 * v[k] );
1301 s = ( ( f[q] + q * q ) - ( f[v[k]] + ( v[k] * v[k] ) ) ) / ( 2 * q - 2 * v[k] );
1310 for (
int q = 0; q <= n - 1; q++ )
1312 while ( z[k + 1] < q )
1314 d[q] = ( q - v[k] ) * ( q - v[k] ) + f[v[k]];
1319 void QgsShapeburstFillSymbolLayer::distanceTransform2d(
double *im,
int width,
int height )
1321 int maxDimension = std::max( width, height );
1322 double *f =
new double[ maxDimension ];
1323 int *v =
new int[ maxDimension ];
1324 double *z =
new double[ maxDimension + 1 ];
1325 double *d =
new double[ maxDimension ];
1328 for (
int x = 0; x < width; x++ )
1330 for (
int y = 0; y < height; y++ )
1332 f[y] = im[ x + y * width ];
1334 distanceTransform1d( f, height, v, z, d );
1335 for (
int y = 0; y < height; y++ )
1337 im[ x + y * width ] = d[y];
1342 for (
int y = 0; y < height; y++ )
1344 for (
int x = 0; x < width; x++ )
1346 f[x] = im[ x + y * width ];
1348 distanceTransform1d( f, width, v, z, d );
1349 for (
int x = 0; x < width; x++ )
1351 im[ x + y * width ] = d[x];
1362 double *QgsShapeburstFillSymbolLayer::distanceTransform( QImage *im )
1364 int width = im->width();
1365 int height = im->height();
1367 double *dtArray =
new double[width * height];
1372 for (
int heightIndex = 0; heightIndex < height; ++heightIndex )
1374 const QRgb *scanLine =
reinterpret_cast< const QRgb *
>( im->constScanLine( heightIndex ) );
1375 for (
int widthIndex = 0; widthIndex < width; ++widthIndex )
1377 tmpRgb = scanLine[widthIndex];
1378 if ( qRed( tmpRgb ) == 0 )
1386 dtArray[ idx ] =
INF;
1393 distanceTransform2d( dtArray, width, height );
1398 void QgsShapeburstFillSymbolLayer::dtArrayToQImage(
double *array, QImage *im,
QgsColorRamp *ramp,
double layerAlpha,
bool useWholeShape,
int maxPixelDistance )
1400 int width = im->width();
1401 int height = im->height();
1404 double maxDistanceValue;
1409 double dtMaxValue = array[0];
1410 for (
int i = 1; i < ( width * height ); ++i )
1412 if ( array[i] > dtMaxValue )
1414 dtMaxValue = array[i];
1419 maxDistanceValue = std::sqrt( dtMaxValue );
1424 maxDistanceValue = maxPixelDistance;
1429 double squaredVal = 0;
1432 bool layerHasAlpha = layerAlpha < 1.0;
1434 for (
int heightIndex = 0; heightIndex < height; ++heightIndex )
1436 QRgb *scanLine =
reinterpret_cast< QRgb *
>( im->scanLine( heightIndex ) );
1437 for (
int widthIndex = 0; widthIndex < width; ++widthIndex )
1440 squaredVal = array[idx];
1443 if ( maxDistanceValue > 0 )
1445 pixVal = squaredVal > 0 ? std::min( ( std::sqrt( squaredVal ) / maxDistanceValue ), 1.0 ) : 0;
1453 pixColor = ramp->
color( pixVal );
1455 int pixAlpha = pixColor.alpha();
1456 if ( ( layerHasAlpha ) || ( pixAlpha != 255 ) )
1459 double alpha = pixAlpha * layerAlpha;
1464 scanLine[widthIndex] = pixColor.rgba();
1475 map[QStringLiteral(
"color_type" )] = QString::number( mColorType );
1476 map[QStringLiteral(
"blur_radius" )] = QString::number( mBlurRadius );
1477 map[QStringLiteral(
"use_whole_shape" )] = QString::number( mUseWholeShape );
1478 map[QStringLiteral(
"max_distance" )] = QString::number( mMaxDistance );
1481 map[QStringLiteral(
"ignore_rings" )] = QString::number( mIgnoreRings );
1485 if ( mGradientRamp )
1487 map.unite( mGradientRamp->properties() );
1495 std::unique_ptr< QgsShapeburstFillSymbolLayer > sl = qgis::make_unique< QgsShapeburstFillSymbolLayer >(
mColor, mColor2, mColorType, mBlurRadius, mUseWholeShape, mMaxDistance );
1496 if ( mGradientRamp )
1500 sl->setDistanceUnit( mDistanceUnit );
1501 sl->setDistanceMapUnitScale( mDistanceMapUnitScale );
1502 sl->setIgnoreRings( mIgnoreRings );
1503 sl->setOffset( mOffset );
1504 sl->setOffsetUnit( mOffsetUnit );
1505 sl->setOffsetMapUnitScale( mOffsetMapUnitScale );
1508 return sl.release();
1513 double offsetBleed = context.
convertToPainterUnits( std::max( std::fabs( mOffset.x() ), std::fabs( mOffset.y() ) ), mOffsetUnit, mOffsetMapUnitScale );
1519 mDistanceUnit = unit;
1525 if ( mDistanceUnit == mOffsetUnit )
1527 return mDistanceUnit;
1534 mDistanceMapUnitScale = scale;
1535 mOffsetMapUnitScale = scale;
1540 if ( mDistanceMapUnitScale == mOffsetMapUnitScale )
1542 return mDistanceMapUnitScale;
1564 applyDataDefinedSettings( context );
1566 p->setPen( QPen( Qt::NoPen ) );
1568 QTransform bkTransform = mBrush.transform();
1572 QPointF leftCorner = points.boundingRect().topLeft();
1573 QTransform t = mBrush.transform();
1574 t.translate( leftCorner.x(), leftCorner.y() );
1575 mBrush.setTransform( t );
1584 p->setBrush( QBrush( selColor ) );
1590 QTransform t = mBrush.transform();
1591 t.rotate( mNextAngle );
1592 mBrush.setTransform( t );
1594 p->setBrush( mBrush );
1601 QList<QPolygonF>::const_iterator ringIt = rings->constBegin();
1602 for ( ; ringIt != rings->constEnd(); ++ringIt )
1609 mBrush.setTransform( bkTransform );
1616 mStroke.reset(
nullptr );
1629 mStroke.reset( lineSymbol );
1639 mStrokeWidthUnit = unit;
1644 return mStrokeWidthUnit;
1649 mStrokeWidthMapUnitScale = scale;
1654 return mStrokeWidthMapUnitScale;
1659 if ( mStroke && mStroke->symbolLayer( 0 ) )
1661 double subLayerBleed = mStroke->symbolLayer( 0 )->estimateMaxBleed( context );
1662 return subLayerBleed;
1669 double width = mStrokeWidth;
1680 Q_UNUSED( context );
1683 return QColor( Qt::black );
1685 return mStroke->color();
1690 return Qt::SolidLine;
1694 return Qt::SolidLine;
1698 return mStroke->dxfPenStyle();
1707 attr.unite( mStroke->usedAttributes( context ) );
1715 if ( mStroke && mStroke->hasDataDefinedProperties() )
1725 , mPatternWidth( width )
1730 mColor = QColor( 255, 255, 255 );
1731 setDefaultSvgParams();
1736 , mPatternWidth( width )
1737 , mSvgData( svgData )
1742 mColor = QColor( 255, 255, 255 );
1744 setDefaultSvgParams();
1750 mPatternWidthUnit = unit;
1751 mSvgStrokeWidthUnit = unit;
1753 mStroke->setOutputUnit( unit );
1759 if ( mPatternWidthUnit != unit || mSvgStrokeWidthUnit != unit ||
mStrokeWidthUnit != unit )
1769 mPatternWidthMapUnitScale = scale;
1770 mSvgStrokeWidthMapUnitScale = scale;
1777 mPatternWidthMapUnitScale == mSvgStrokeWidthMapUnitScale &&
1780 return mPatternWidthMapUnitScale;
1790 mSvgFilePath = svgPath;
1791 setDefaultSvgParams();
1801 if ( properties.contains( QStringLiteral(
"width" ) ) )
1803 width = properties[QStringLiteral(
"width" )].toDouble();
1805 if ( properties.contains( QStringLiteral(
"svgFile" ) ) )
1807 svgFilePath = properties[QStringLiteral(
"svgFile" )];
1809 if ( properties.contains( QStringLiteral(
"angle" ) ) )
1811 angle = properties[QStringLiteral(
"angle" )].toDouble();
1814 std::unique_ptr< QgsSVGFillSymbolLayer > symbolLayer;
1815 if ( !svgFilePath.isEmpty() )
1817 symbolLayer = qgis::make_unique< QgsSVGFillSymbolLayer >(
svgFilePath, width,
angle );
1821 if ( properties.contains( QStringLiteral(
"data" ) ) )
1823 data = QByteArray::fromHex( properties[QStringLiteral(
"data" )].toLocal8Bit() );
1825 symbolLayer = qgis::make_unique< QgsSVGFillSymbolLayer >( data, width,
angle );
1829 if ( properties.contains( QStringLiteral(
"svgFillColor" ) ) )
1834 else if ( properties.contains( QStringLiteral(
"color" ) ) )
1838 if ( properties.contains( QStringLiteral(
"svgOutlineColor" ) ) )
1843 else if ( properties.contains( QStringLiteral(
"outline_color" ) ) )
1847 else if ( properties.contains( QStringLiteral(
"line_color" ) ) )
1851 if ( properties.contains( QStringLiteral(
"svgOutlineWidth" ) ) )
1854 symbolLayer->setSvgStrokeWidth( properties[QStringLiteral(
"svgOutlineWidth" )].toDouble() );
1856 else if ( properties.contains( QStringLiteral(
"outline_width" ) ) )
1858 symbolLayer->setSvgStrokeWidth( properties[QStringLiteral(
"outline_width" )].toDouble() );
1860 else if ( properties.contains( QStringLiteral(
"line_width" ) ) )
1862 symbolLayer->setSvgStrokeWidth( properties[QStringLiteral(
"line_width" )].toDouble() );
1866 if ( properties.contains( QStringLiteral(
"pattern_width_unit" ) ) )
1870 if ( properties.contains( QStringLiteral(
"pattern_width_map_unit_scale" ) ) )
1874 if ( properties.contains( QStringLiteral(
"svg_outline_width_unit" ) ) )
1878 if ( properties.contains( QStringLiteral(
"svg_outline_width_map_unit_scale" ) ) )
1882 if ( properties.contains( QStringLiteral(
"outline_width_unit" ) ) )
1886 if ( properties.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
1891 symbolLayer->restoreOldDataDefinedProperties( properties );
1893 return symbolLayer.release();
1898 QgsStringMap::iterator it = properties.find( QStringLiteral(
"svgFile" ) );
1899 if ( it != properties.end() )
1910 return QStringLiteral(
"SVGFill" );
1918 if ( mSvgViewBox.isNull() )
1925 if ( static_cast< int >( size ) < 1.0 || 10000.0 < size )
1927 brush.setTextureImage( QImage() );
1931 bool fitsInCache =
true;
1939 double hwRatio = 1.0;
1940 if ( patternPict.width() > 0 )
1942 hwRatio =
static_cast< double >( patternPict.height() ) / static_cast< double >( patternPict.width() );
1944 patternImage = QImage( static_cast< int >( size ), static_cast< int >( size * hwRatio ), QImage::Format_ARGB32_Premultiplied );
1945 patternImage.fill( 0 );
1947 QPainter p( &patternImage );
1948 p.drawPicture( QPointF( size / 2, size * hwRatio / 2 ), patternPict );
1951 QTransform brushTransform;
1954 QImage transparentImage = patternImage.copy();
1956 brush.setTextureImage( transparentImage );
1960 brush.setTextureImage( patternImage );
1962 brush.setTransform( brushTransform );
1969 applyPattern(
mBrush, mSvgFilePath, mPatternWidth, mPatternWidthUnit,
mColor, mSvgStrokeColor, mSvgStrokeWidth, mSvgStrokeWidthUnit, context, mPatternWidthMapUnitScale, mSvgStrokeWidthMapUnitScale );
1988 if ( !mSvgFilePath.isEmpty() )
1990 map.insert( QStringLiteral(
"svgFile" ), mSvgFilePath );
1994 map.insert( QStringLiteral(
"data" ), QString( mSvgData.toHex() ) );
1997 map.insert( QStringLiteral(
"width" ), QString::number( mPatternWidth ) );
1998 map.insert( QStringLiteral(
"angle" ), QString::number(
mAngle ) );
2003 map.insert( QStringLiteral(
"outline_width" ), QString::number( mSvgStrokeWidth ) );
2017 std::unique_ptr< QgsSVGFillSymbolLayer > clonedLayer;
2018 if ( !mSvgFilePath.isEmpty() )
2020 clonedLayer = qgis::make_unique< QgsSVGFillSymbolLayer >( mSvgFilePath, mPatternWidth,
mAngle );
2022 clonedLayer->setSvgStrokeColor( mSvgStrokeColor );
2023 clonedLayer->setSvgStrokeWidth( mSvgStrokeWidth );
2027 clonedLayer = qgis::make_unique< QgsSVGFillSymbolLayer >( mSvgData, mPatternWidth,
mAngle );
2030 clonedLayer->setPatternWidthUnit( mPatternWidthUnit );
2031 clonedLayer->setPatternWidthMapUnitScale( mPatternWidthMapUnitScale );
2032 clonedLayer->setSvgStrokeWidthUnit( mSvgStrokeWidthUnit );
2033 clonedLayer->setSvgStrokeWidthMapUnitScale( mSvgStrokeWidthMapUnitScale );
2039 clonedLayer->setSubSymbol(
mStroke->clone() );
2043 return clonedLayer.release();
2048 QDomElement symbolizerElem = doc.createElement( QStringLiteral(
"se:PolygonSymbolizer" ) );
2049 if ( !props.value( QStringLiteral(
"uom" ), QString() ).isEmpty() )
2050 symbolizerElem.setAttribute( QStringLiteral(
"uom" ), props.value( QStringLiteral(
"uom" ), QString() ) );
2051 element.appendChild( symbolizerElem );
2055 QDomElement fillElem = doc.createElement( QStringLiteral(
"se:Fill" ) );
2056 symbolizerElem.appendChild( fillElem );
2058 QDomElement graphicFillElem = doc.createElement( QStringLiteral(
"se:GraphicFill" ) );
2059 fillElem.appendChild( graphicFillElem );
2061 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
2062 graphicFillElem.appendChild( graphicElem );
2064 if ( !mSvgFilePath.isEmpty() )
2075 symbolizerElem.appendChild( doc.createComment( QStringLiteral(
"SVG from data not implemented yet" ) ) );
2081 double angle = props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toDouble( &ok );
2084 angleFunc = QStringLiteral(
"%1 + %2" ).arg( props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ) ).arg(
mAngle );
2088 angleFunc = QString::number( angle +
mAngle );
2097 mStroke->toSld( doc, element, props );
2103 QString path, mimeType;
2105 Qt::PenStyle penStyle;
2106 double size, strokeWidth;
2108 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
2109 if ( fillElem.isNull() )
2112 QDomElement graphicFillElem = fillElem.firstChildElement( QStringLiteral(
"GraphicFill" ) );
2113 if ( graphicFillElem.isNull() )
2116 QDomElement graphicElem = graphicFillElem.firstChildElement( QStringLiteral(
"Graphic" ) );
2117 if ( graphicElem.isNull() )
2123 if ( mimeType != QLatin1String(
"image/svg+xml" ) )
2128 QString uom = element.attribute( QStringLiteral(
"uom" ) );
2137 double d = angleFunc.toDouble( &ok );
2142 std::unique_ptr< QgsSVGFillSymbolLayer > sl = qgis::make_unique< QgsSVGFillSymbolLayer >( path, size,
angle );
2143 sl->setOutputUnit( QgsUnitTypes::RenderUnit::RenderPixels );
2144 sl->setSvgFillColor( fillColor );
2145 sl->setSvgStrokeColor( strokeColor );
2146 sl->setSvgStrokeWidth( strokeWidth );
2149 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
2150 if ( !strokeElem.isNull() )
2161 return sl.release();
2179 double width = mPatternWidth;
2185 QString svgFile = mSvgFilePath;
2204 double strokeWidth = mSvgStrokeWidth;
2210 applyPattern(
mBrush, svgFile, width, mPatternWidthUnit, svgFillColor, svgStrokeColor, strokeWidth,
2211 mSvgStrokeWidthUnit, context, mPatternWidthMapUnitScale, mSvgStrokeWidthMapUnitScale );
2215 void QgsSVGFillSymbolLayer::storeViewBox()
2217 if ( !mSvgData.isEmpty() )
2219 QSvgRenderer r( mSvgData );
2222 mSvgViewBox = r.viewBoxF();
2227 mSvgViewBox = QRectF();
2230 void QgsSVGFillSymbolLayer::setDefaultSvgParams()
2232 if ( mSvgFilePath.isEmpty() )
2237 bool hasFillParam, hasFillOpacityParam, hasStrokeParam, hasStrokeWidthParam, hasStrokeOpacityParam;
2238 bool hasDefaultFillColor, hasDefaultFillOpacity, hasDefaultStrokeColor, hasDefaultStrokeWidth, hasDefaultStrokeOpacity;
2239 QColor defaultFillColor, defaultStrokeColor;
2240 double defaultStrokeWidth, defaultFillOpacity, defaultStrokeOpacity;
2242 hasFillOpacityParam, hasDefaultFillOpacity, defaultFillOpacity,
2243 hasStrokeParam, hasDefaultStrokeColor, defaultStrokeColor,
2244 hasStrokeWidthParam, hasDefaultStrokeWidth, defaultStrokeWidth,
2245 hasStrokeOpacityParam, hasDefaultStrokeOpacity, defaultStrokeOpacity );
2247 double newFillOpacity = hasFillOpacityParam ?
mColor.alphaF() : 1.0;
2248 double newStrokeOpacity = hasStrokeOpacityParam ? mSvgStrokeColor.alphaF() : 1.0;
2250 if ( hasDefaultFillColor )
2252 mColor = defaultFillColor;
2253 mColor.setAlphaF( newFillOpacity );
2255 if ( hasDefaultFillOpacity )
2257 mColor.setAlphaF( defaultFillOpacity );
2259 if ( hasDefaultStrokeColor )
2261 mSvgStrokeColor = defaultStrokeColor;
2262 mSvgStrokeColor.setAlphaF( newStrokeOpacity );
2264 if ( hasDefaultStrokeOpacity )
2266 mSvgStrokeColor.setAlphaF( defaultStrokeOpacity );
2268 if ( hasDefaultStrokeWidth )
2270 mSvgStrokeWidth = defaultStrokeWidth;
2296 return mFillLineSymbol ? mFillLineSymbol->
color() :
mColor;
2301 delete mFillLineSymbol;
2316 delete mFillLineSymbol;
2317 mFillLineSymbol = lineSymbol;
2328 return mFillLineSymbol;
2334 if ( mFillLineSymbol )
2356 mDistanceUnit = unit;
2357 mLineWidthUnit = unit;
2364 if ( mDistanceUnit != unit || mLineWidthUnit != unit || mOffsetUnit != unit )
2374 mDistanceMapUnitScale = scale;
2375 mLineWidthMapUnitScale = scale;
2376 mOffsetMapUnitScale = scale;
2382 mDistanceMapUnitScale == mLineWidthMapUnitScale &&
2383 mLineWidthMapUnitScale == mOffsetMapUnitScale )
2385 return mDistanceMapUnitScale;
2392 std::unique_ptr< QgsLinePatternFillSymbolLayer > patternLayer = qgis::make_unique< QgsLinePatternFillSymbolLayer >();
2398 QColor
color( Qt::black );
2401 if ( properties.contains( QStringLiteral(
"lineangle" ) ) )
2404 lineAngle = properties[QStringLiteral(
"lineangle" )].toDouble();
2406 else if ( properties.contains( QStringLiteral(
"angle" ) ) )
2408 lineAngle = properties[QStringLiteral(
"angle" )].toDouble();
2410 patternLayer->setLineAngle( lineAngle );
2412 if ( properties.contains( QStringLiteral(
"distance" ) ) )
2414 distance = properties[QStringLiteral(
"distance" )].toDouble();
2416 patternLayer->setDistance( distance );
2418 if ( properties.contains( QStringLiteral(
"linewidth" ) ) )
2421 lineWidth = properties[QStringLiteral(
"linewidth" )].toDouble();
2423 else if ( properties.contains( QStringLiteral(
"outline_width" ) ) )
2425 lineWidth = properties[QStringLiteral(
"outline_width" )].toDouble();
2427 else if ( properties.contains( QStringLiteral(
"line_width" ) ) )
2429 lineWidth = properties[QStringLiteral(
"line_width" )].toDouble();
2431 patternLayer->setLineWidth( lineWidth );
2433 if ( properties.contains( QStringLiteral(
"color" ) ) )
2437 else if ( properties.contains( QStringLiteral(
"outline_color" ) ) )
2441 else if ( properties.contains( QStringLiteral(
"line_color" ) ) )
2445 patternLayer->setColor( color );
2447 if ( properties.contains( QStringLiteral(
"offset" ) ) )
2449 offset = properties[QStringLiteral(
"offset" )].toDouble();
2451 patternLayer->setOffset( offset );
2454 if ( properties.contains( QStringLiteral(
"distance_unit" ) ) )
2458 if ( properties.contains( QStringLiteral(
"distance_map_unit_scale" ) ) )
2462 if ( properties.contains( QStringLiteral(
"line_width_unit" ) ) )
2466 else if ( properties.contains( QStringLiteral(
"outline_width_unit" ) ) )
2470 if ( properties.contains( QStringLiteral(
"line_width_map_unit_scale" ) ) )
2474 if ( properties.contains( QStringLiteral(
"offset_unit" ) ) )
2478 if ( properties.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
2482 if ( properties.contains( QStringLiteral(
"outline_width_unit" ) ) )
2486 if ( properties.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
2491 patternLayer->restoreOldDataDefinedProperties( properties );
2493 return patternLayer.release();
2498 return QStringLiteral(
"LinePatternFill" );
2503 mBrush.setTextureImage( QImage() );
2505 if ( !mFillLineSymbol )
2510 std::unique_ptr< QgsLineSymbol > fillLineSymbol( mFillLineSymbol->
clone() );
2511 if ( !fillLineSymbol )
2518 double outputPixelDist = ctx.
convertToPainterUnits( distance, mDistanceUnit, mDistanceMapUnitScale );
2526 outputPixelOffset = std::fmod( outputPixelOffset, outputPixelDist );
2527 if ( outputPixelOffset > outputPixelDist / 2.0 )
2528 outputPixelOffset -= outputPixelDist;
2532 double outputPixelBleed = 0;
2533 double outputPixelInterval = 0;
2534 for (
int i = 0; i < fillLineSymbol->symbolLayerCount(); i++ )
2538 outputPixelBleed = std::max( outputPixelBleed, outputPixelLayerBleed );
2541 if ( markerLineLayer )
2550 outputPixelInterval = std::max( outputPixelInterval, outputPixelLayerInterval );
2554 if ( outputPixelInterval > 0 )
2558 double intervalScale = std::round( outputPixelInterval ) / outputPixelInterval;
2559 outputPixelInterval = std::round( outputPixelInterval );
2561 for (
int i = 0; i < fillLineSymbol->symbolLayerCount(); i++ )
2566 if ( markerLineLayer )
2580 height = outputPixelDist;
2581 width = outputPixelInterval > 0 ? outputPixelInterval : height;
2585 width = outputPixelDist;
2586 height = outputPixelInterval > 0 ? outputPixelInterval : width;
2590 height = outputPixelDist / std::cos(
lineAngle * M_PI / 180 );
2591 width = outputPixelDist / std::sin(
lineAngle * M_PI / 180 );
2594 lineAngle = 180 * std::atan2( static_cast< double >( height ), static_cast< double >( width ) ) / M_PI;
2600 height = std::abs( height );
2601 width = std::abs( width );
2603 outputPixelDist = std::abs( height * std::cos(
lineAngle * M_PI / 180 ) );
2607 int offsetHeight =
static_cast< int >( std::round( outputPixelOffset / std::cos(
lineAngle * M_PI / 180 ) ) );
2608 outputPixelOffset = offsetHeight * std::cos(
lineAngle * M_PI / 180 );
2617 int bufferMulti =
static_cast< int >( std::max( std::ceil( outputPixelBleed / width ), std::ceil( outputPixelBleed / width ) ) );
2621 bufferMulti = std::max( bufferMulti, 1 );
2623 int xBuffer = width * bufferMulti;
2624 int yBuffer = height * bufferMulti;
2625 int innerWidth = width;
2626 int innerHeight = height;
2627 width += 2 * xBuffer;
2628 height += 2 * yBuffer;
2631 if ( width > 10000 || height > 10000 || width == 0 || height == 0 )
2636 QImage patternImage( width, height, QImage::Format_ARGB32 );
2637 patternImage.fill( 0 );
2639 QPointF p1, p2, p3, p4, p5, p6;
2642 p1 = QPointF( 0, yBuffer );
2643 p2 = QPointF( width, yBuffer );
2644 p3 = QPointF( 0, yBuffer + innerHeight );
2645 p4 = QPointF( width, yBuffer + innerHeight );
2649 p1 = QPointF( xBuffer, height );
2650 p2 = QPointF( xBuffer, 0 );
2651 p3 = QPointF( xBuffer + innerWidth, height );
2652 p4 = QPointF( xBuffer + innerWidth, 0 );
2656 dx = outputPixelDist * std::cos( ( 90 -
lineAngle ) * M_PI / 180.0 );
2657 dy = outputPixelDist * std::sin( ( 90 -
lineAngle ) * M_PI / 180.0 );
2658 p1 = QPointF( 0, height );
2659 p2 = QPointF( width, 0 );
2660 p3 = QPointF( -dx, height - dy );
2661 p4 = QPointF( width - dx, -dy );
2662 p5 = QPointF( dx, height + dy );
2663 p6 = QPointF( width + dx, dy );
2667 dx = outputPixelDist * std::cos( ( 90 -
lineAngle ) * M_PI / 180.0 );
2668 dy = outputPixelDist * std::sin( ( 90 -
lineAngle ) * M_PI / 180.0 );
2669 p1 = QPointF( width, 0 );
2670 p2 = QPointF( 0, height );
2671 p3 = QPointF( width - dx, -dy );
2672 p4 = QPointF( -dx, height - dy );
2673 p5 = QPointF( width + dx, dy );
2674 p6 = QPointF( dx, height + dy );
2678 dy = outputPixelDist * std::cos( ( 180 -
lineAngle ) * M_PI / 180 );
2679 dx = outputPixelDist * std::sin( ( 180 -
lineAngle ) * M_PI / 180 );
2680 p1 = QPointF( 0, 0 );
2681 p2 = QPointF( width, height );
2682 p5 = QPointF( dx, -dy );
2683 p6 = QPointF( width + dx, height - dy );
2684 p3 = QPointF( -dx, dy );
2685 p4 = QPointF( width - dx, height + dy );
2689 dy = outputPixelDist * std::cos( ( 180 -
lineAngle ) * M_PI / 180 );
2690 dx = outputPixelDist * std::sin( ( 180 -
lineAngle ) * M_PI / 180 );
2691 p1 = QPointF( width, height );
2692 p2 = QPointF( 0, 0 );
2693 p5 = QPointF( width + dx, height - dy );
2694 p6 = QPointF( dx, -dy );
2695 p3 = QPointF( width - dx, height + dy );
2696 p4 = QPointF( -dx, dy );
2703 p3 = QPointF( tempPt.x(), tempPt.y() );
2705 p4 = QPointF( tempPt.x(), tempPt.y() );
2707 p5 = QPointF( tempPt.x(), tempPt.y() );
2709 p6 = QPointF( tempPt.x(), tempPt.y() );
2713 p1 = QPointF( tempPt.x(), tempPt.y() );
2715 p2 = QPointF( tempPt.x(), tempPt.y() );
2718 QPainter p( &patternImage );
2722 p.setRenderHint( QPainter::Antialiasing,
false );
2723 QPen pen( QColor( Qt::black ) );
2724 pen.setWidthF( 0.1 );
2725 pen.setCapStyle( Qt::FlatCap );
2730 QPolygon polygon = QPolygon() << QPoint( 0, 0 ) << QPoint( width - 1, 0 ) << QPoint( width - 1, height - 1 ) << QPoint( 0, height - 1 ) << QPoint( 0, 0 );
2731 p.drawPolygon( polygon );
2733 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 );
2734 p.drawPolygon( polygon );
2740 p.setRenderHint( QPainter::Antialiasing,
true );
2751 fillLineSymbol->startRender( lineRenderContext, context.
fields() );
2753 QVector<QPolygonF> polygons;
2754 polygons.append( QPolygonF() << p1 << p2 );
2755 polygons.append( QPolygonF() << p3 << p4 );
2758 polygons.append( QPolygonF() << p5 << p6 );
2761 for (
const QPolygonF &polygon : qgis::as_const( polygons ) )
2763 fillLineSymbol->renderPolyline( polygon, context.
feature(), lineRenderContext, -1, context.
selected() );
2766 fillLineSymbol->stopRender( lineRenderContext );
2770 patternImage = patternImage.copy( xBuffer, yBuffer, patternImage.width() - 2 * xBuffer, patternImage.height() - 2 * yBuffer );
2775 QImage transparentImage = patternImage.copy();
2777 brush.setTextureImage( transparentImage );
2781 brush.setTextureImage( patternImage );
2784 QTransform brushTransform;
2785 brush.setTransform( brushTransform );
2790 applyPattern( context,
mBrush, mLineAngle, mDistance );
2792 if ( mFillLineSymbol )
2800 if ( mFillLineSymbol )
2809 map.insert( QStringLiteral(
"angle" ), QString::number( mLineAngle ) );
2810 map.insert( QStringLiteral(
"distance" ), QString::number( mDistance ) );
2811 map.insert( QStringLiteral(
"line_width" ), QString::number( mLineWidth ) );
2813 map.insert( QStringLiteral(
"offset" ), QString::number( mOffset ) );
2828 if ( mFillLineSymbol )
2839 QDomElement symbolizerElem = doc.createElement( QStringLiteral(
"se:PolygonSymbolizer" ) );
2840 if ( !props.value( QStringLiteral(
"uom" ), QString() ).isEmpty() )
2841 symbolizerElem.setAttribute( QStringLiteral(
"uom" ), props.value( QStringLiteral(
"uom" ), QString() ) );
2842 element.appendChild( symbolizerElem );
2847 QDomElement fillElem = doc.createElement( QStringLiteral(
"se:Fill" ) );
2848 symbolizerElem.appendChild( fillElem );
2850 QDomElement graphicFillElem = doc.createElement( QStringLiteral(
"se:GraphicFill" ) );
2851 fillElem.appendChild( graphicFillElem );
2853 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
2854 graphicFillElem.appendChild( graphicElem );
2857 QColor lineColor = mFillLineSymbol ? mFillLineSymbol->
color() : QColor();
2858 double lineWidth = mFillLineSymbol ? mFillLineSymbol->
width() : 0.0;
2866 double angle = props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toDouble( &ok );
2869 angleFunc = QStringLiteral(
"%1 + %2" ).arg( props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ) ).arg( mLineAngle );
2873 angleFunc = QString::number( angle + mLineAngle );
2878 QPointF lineOffset( std::sin( mLineAngle ) * mOffset, std::cos( mLineAngle ) * mOffset );
2885 QString featureStyle;
2886 featureStyle.append(
"Brush(" );
2887 featureStyle.append( QStringLiteral(
"fc:%1" ).arg(
mColor.name() ) );
2888 featureStyle.append( QStringLiteral(
",bc:%1" ).arg( QStringLiteral(
"#00000000" ) ) );
2889 featureStyle.append(
",id:\"ogr-brush-2\"" );
2890 featureStyle.append( QStringLiteral(
",a:%1" ).arg( mLineAngle ) );
2891 featureStyle.append( QStringLiteral(
",s:%1" ).arg( mLineWidth * widthScaleFactor ) );
2892 featureStyle.append(
",dx:0mm" );
2893 featureStyle.append( QStringLiteral(
",dy:%1mm" ).arg( mDistance * widthScaleFactor ) );
2894 featureStyle.append(
')' );
2895 return featureStyle;
2918 applyPattern( context,
mBrush, lineAngle, distance );
2926 Qt::PenStyle lineStyle;
2928 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
2929 if ( fillElem.isNull() )
2932 QDomElement graphicFillElem = fillElem.firstChildElement( QStringLiteral(
"GraphicFill" ) );
2933 if ( graphicFillElem.isNull() )
2936 QDomElement graphicElem = graphicFillElem.firstChildElement( QStringLiteral(
"Graphic" ) );
2937 if ( graphicElem.isNull() )
2943 if ( name != QLatin1String(
"horline" ) )
2951 double d = angleFunc.toDouble( &ok );
2960 offset = std::sqrt( std::pow( vectOffset.x(), 2 ) + std::pow( vectOffset.y(), 2 ) );
2963 QString uom = element.attribute( QStringLiteral(
"uom" ) );
2967 std::unique_ptr< QgsLinePatternFillSymbolLayer > sl = qgis::make_unique< QgsLinePatternFillSymbolLayer >();
2968 sl->setOutputUnit( QgsUnitTypes::RenderUnit::RenderPixels );
2969 sl->setColor( lineColor );
2970 sl->setLineWidth( lineWidth );
2971 sl->setLineAngle( angle );
2972 sl->setOffset( offset );
2973 sl->setDistance( size );
2976 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
2977 if ( !strokeElem.isNull() )
2988 return sl.release();
3057 std::unique_ptr< QgsPointPatternFillSymbolLayer > layer = qgis::make_unique< QgsPointPatternFillSymbolLayer >();
3058 if ( properties.contains( QStringLiteral(
"distance_x" ) ) )
3060 layer->setDistanceX( properties[QStringLiteral(
"distance_x" )].toDouble() );
3062 if ( properties.contains( QStringLiteral(
"distance_y" ) ) )
3064 layer->setDistanceY( properties[QStringLiteral(
"distance_y" )].toDouble() );
3066 if ( properties.contains( QStringLiteral(
"displacement_x" ) ) )
3068 layer->setDisplacementX( properties[QStringLiteral(
"displacement_x" )].toDouble() );
3070 if ( properties.contains( QStringLiteral(
"displacement_y" ) ) )
3072 layer->setDisplacementY( properties[QStringLiteral(
"displacement_y" )].toDouble() );
3075 if ( properties.contains( QStringLiteral(
"distance_x_unit" ) ) )
3079 if ( properties.contains( QStringLiteral(
"distance_x_map_unit_scale" ) ) )
3083 if ( properties.contains( QStringLiteral(
"distance_y_unit" ) ) )
3087 if ( properties.contains( QStringLiteral(
"distance_y_map_unit_scale" ) ) )
3091 if ( properties.contains( QStringLiteral(
"displacement_x_unit" ) ) )
3095 if ( properties.contains( QStringLiteral(
"displacement_x_map_unit_scale" ) ) )
3099 if ( properties.contains( QStringLiteral(
"displacement_y_unit" ) ) )
3103 if ( properties.contains( QStringLiteral(
"displacement_y_map_unit_scale" ) ) )
3107 if ( properties.contains( QStringLiteral(
"outline_width_unit" ) ) )
3111 if ( properties.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
3118 return layer.release();
3123 return QStringLiteral(
"PointPatternFill" );
3134 if ( width > 10000 || height > 10000 )
3137 brush.setTextureImage( img );
3141 QImage patternImage( width, height, QImage::Format_ARGB32 );
3142 patternImage.fill( 0 );
3146 QPainter p( &patternImage );
3156 p.setRenderHint( QPainter::Antialiasing,
true );
3185 QImage transparentImage = patternImage.copy();
3187 brush.setTextureImage( transparentImage );
3191 brush.setTextureImage( patternImage );
3193 QTransform brushTransform;
3194 brush.setTransform( brushTransform );
3218 map.insert( QStringLiteral(
"distance_x" ), QString::number(
mDistanceX ) );
3219 map.insert( QStringLiteral(
"distance_y" ), QString::number(
mDistanceY ) );
3220 map.insert( QStringLiteral(
"displacement_x" ), QString::number(
mDisplacementX ) );
3221 map.insert( QStringLiteral(
"displacement_y" ), QString::number(
mDisplacementY ) );
3251 QDomElement symbolizerElem = doc.createElement( QStringLiteral(
"se:PolygonSymbolizer" ) );
3252 if ( !props.value( QStringLiteral(
"uom" ), QString() ).isEmpty() )
3253 symbolizerElem.setAttribute( QStringLiteral(
"uom" ), props.value( QStringLiteral(
"uom" ), QString() ) );
3254 element.appendChild( symbolizerElem );
3259 QDomElement fillElem = doc.createElement( QStringLiteral(
"se:Fill" ) );
3260 symbolizerElem.appendChild( fillElem );
3262 QDomElement graphicFillElem = doc.createElement( QStringLiteral(
"se:GraphicFill" ) );
3263 fillElem.appendChild( graphicFillElem );
3270 symbolizerElem.appendChild( distanceElem );
3276 QString errorMsg = QStringLiteral(
"MarkerSymbolLayerV2 expected, %1 found. Skip it." ).arg( layer->
layerType() );
3277 graphicFillElem.appendChild( doc.createComment( errorMsg ) );
3288 Q_UNUSED( element );
3341 applyPattern( context,
mBrush, distanceX, distanceY, displacementX, displacementY );
3390 std::unique_ptr< QgsCentroidFillSymbolLayer > sl = qgis::make_unique< QgsCentroidFillSymbolLayer >();
3392 if ( properties.contains( QStringLiteral(
"point_on_surface" ) ) )
3393 sl->setPointOnSurface( properties[QStringLiteral(
"point_on_surface" )].toInt() != 0 );
3394 if ( properties.contains( QStringLiteral(
"point_on_all_parts" ) ) )
3395 sl->setPointOnAllParts( properties[QStringLiteral(
"point_on_all_parts" )].toInt() != 0 );
3399 return sl.release();
3404 return QStringLiteral(
"CentroidFill" );
3409 mMarker->setColor( color );
3415 return mMarker ? mMarker->color() :
mColor;
3420 mMarker->setOpacity( context.
opacity() );
3423 mCurrentFeatureId = -1;
3424 mBiggestPartIndex = 0;
3436 if ( !mPointOnAllParts )
3441 if ( feature->
id() != mCurrentFeatureId )
3443 mCurrentFeatureId = feature->
id();
3444 mBiggestPartIndex = 1;
3452 double areaBiggest = 0;
3456 if ( area > areaBiggest )
3459 mBiggestPartIndex = i + 1;
3467 if ( mPointOnAllParts || ( context.
geometryPartNum() == mBiggestPartIndex ) )
3477 map[QStringLiteral(
"point_on_surface" )] = QString::number( mPointOnSurface );
3478 map[QStringLiteral(
"point_on_all_parts" )] = QString::number( mPointOnAllParts );
3484 std::unique_ptr< QgsCentroidFillSymbolLayer > x = qgis::make_unique< QgsCentroidFillSymbolLayer >();
3487 x->setSubSymbol( mMarker->clone() );
3488 x->setPointOnSurface( mPointOnSurface );
3489 x->setPointOnAllParts( mPointOnAllParts );
3500 mMarker->toSld( doc, element, props );
3511 std::unique_ptr< QgsMarkerSymbol > marker(
new QgsMarkerSymbol( layers ) );
3513 std::unique_ptr< QgsCentroidFillSymbolLayer > sl = qgis::make_unique< QgsCentroidFillSymbolLayer >();
3514 sl->setSubSymbol( marker.release() );
3515 return sl.release();
3521 return mMarker.get();
3532 mMarker.reset( static_cast<QgsMarkerSymbol *>( symbol ) );
3533 mColor = mMarker->color();
3542 attributes.unite( mMarker->usedAttributes( context ) );
3551 if ( mMarker && mMarker->hasDataDefinedProperties() )
3560 mMarker->setOutputUnit( unit );
3568 return mMarker->outputUnit();
3577 mMarker->setMapUnitScale( scale );
3585 return mMarker->mapUnitScale();
3595 , mImageFilePath( imageFilePath )
3609 if ( properties.contains( QStringLiteral(
"imageFile" ) ) )
3611 imagePath = properties[QStringLiteral(
"imageFile" )];
3613 if ( properties.contains( QStringLiteral(
"coordinate_mode" ) ) )
3615 mode =
static_cast< FillCoordinateMode >( properties[QStringLiteral(
"coordinate_mode" )].toInt() );
3617 if ( properties.contains( QStringLiteral(
"alpha" ) ) )
3619 alpha = properties[QStringLiteral(
"alpha" )].toDouble();
3621 if ( properties.contains( QStringLiteral(
"offset" ) ) )
3625 if ( properties.contains( QStringLiteral(
"angle" ) ) )
3627 angle = properties[QStringLiteral(
"angle" )].toDouble();
3629 if ( properties.contains( QStringLiteral(
"width" ) ) )
3631 width = properties[QStringLiteral(
"width" )].toDouble();
3633 std::unique_ptr< QgsRasterFillSymbolLayer > symbolLayer = qgis::make_unique< QgsRasterFillSymbolLayer >( imagePath );
3634 symbolLayer->setCoordinateMode( mode );
3635 symbolLayer->setOpacity( alpha );
3636 symbolLayer->setOffset( offset );
3637 symbolLayer->setAngle( angle );
3638 symbolLayer->setWidth( width );
3639 if ( properties.contains( QStringLiteral(
"offset_unit" ) ) )
3643 if ( properties.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
3647 if ( properties.contains( QStringLiteral(
"width_unit" ) ) )
3651 if ( properties.contains( QStringLiteral(
"width_map_unit_scale" ) ) )
3656 symbolLayer->restoreOldDataDefinedProperties( properties );
3658 return symbolLayer.release();
3663 QgsStringMap::iterator it = properties.find( QStringLiteral(
"imageFile" ) );
3664 if ( it != properties.end() )
3667 it.value() = pathResolver.
writePath( it.value() );
3669 it.value() = pathResolver.
readPath( it.value() );
3681 return QStringLiteral(
"RasterFill" );
3693 if ( !mOffset.isNull() )
3697 p->translate( offset );
3699 if ( mCoordinateMode ==
Feature )
3701 QRectF boundingRect = points.boundingRect();
3702 mBrush.setTransform(
mBrush.transform().translate( boundingRect.left() -
mBrush.transform().dx(),
3703 boundingRect.top() -
mBrush.transform().dy() ) );
3707 if ( !mOffset.isNull() )
3709 p->translate( -offset );
3715 applyPattern(
mBrush, mImageFilePath, mWidth, mOpacity, context );
3720 Q_UNUSED( context );
3726 map[QStringLiteral(
"imageFile" )] = mImageFilePath;
3727 map[QStringLiteral(
"coordinate_mode" )] = QString::number( mCoordinateMode );
3728 map[QStringLiteral(
"alpha" )] = QString::number( mOpacity );
3732 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
3733 map[QStringLiteral(
"width" )] = QString::number( mWidth );
3741 std::unique_ptr< QgsRasterFillSymbolLayer > sl = qgis::make_unique< QgsRasterFillSymbolLayer >( mImageFilePath );
3743 sl->setOpacity( mOpacity );
3744 sl->setOffset( mOffset );
3745 sl->setOffsetUnit( mOffsetUnit );
3746 sl->setOffsetMapUnitScale( mOffsetMapUnitScale );
3748 sl->setWidth( mWidth );
3749 sl->setWidthUnit( mWidthUnit );
3750 sl->setWidthMapUnitScale( mWidthMapUnitScale );
3753 return sl.release();
3758 return context.
convertToPainterUnits( std::max( std::fabs( mOffset.x() ), std::fabs( mOffset.y() ) ), mOffsetUnit, mOffsetMapUnitScale );
3763 mImageFilePath = imagePath;
3768 mCoordinateMode = mode;
3786 if ( !hasWidthExpression && !hasAngleExpression && !hasOpacityExpression && !hasFileExpression )
3792 if ( hasAngleExpression )
3800 if ( !hasWidthExpression && !hasOpacityExpression && !hasFileExpression )
3805 double width = mWidth;
3806 if ( hasWidthExpression )
3812 if ( hasOpacityExpression )
3817 QString file = mImageFilePath;
3818 if ( hasFileExpression )
3823 applyPattern(
mBrush, file, width, opacity, context );
3832 size.setHeight( 0 );
3840 brush.setTextureImage( img );
QgsStringMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
QgsUnitTypes::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
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)
const QgsMapUnitScale & intervalMapUnitScale() const
QgsMapUnitScale mapUnitScale() const override
QColor color2() const
Returns the color used for the endpoint of the shapeburst fill.
#define DEFAULT_SIMPLEFILL_BORDERCOLOR
QPicture svgAsPicture(const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth, double widthScaleFactor, bool forceVectorOutput=false, double fixedAspectRatio=0)
Gets SVG as QPicture&.
QgsUnitTypes::RenderUnit mStrokeWidthUnit
bool hasDataDefinedProperties() const override
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties...
QgsMapUnitScale mapUnitScale() const override
void setForceVectorOutput(bool force)
static QgsSymbolLayer * createFromSld(QDomElement &element)
bool hasDataDefinedProperties() const override
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties...
QgsImageFillSymbolLayer()
static QgsSvgCache * svgCache()
Returns the application's SVG cache, used for caching SVG images and handling parameter replacement w...
double interval() const
Returns the interval between individual markers.
void stopRender(QgsSymbolRenderContext &context) override
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)
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...
Gradient reference point 1 is centroid.
QgsSimpleFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
double mStrokeWidth
Stroke width.
double rendererScale() const
Returns the renderer map scale.
Qt::BrushStyle mBrushStyle
QgsUnitTypes::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
QgsUnitTypes::RenderUnit mDisplacementXUnit
const QgsPathResolver & pathResolver() const
Returns the path resolver for conversion between relative and absolute paths during rendering operati...
double symbologyScale() const
Returns the reference scale for output.
void setColorRamp(QgsColorRamp *ramp)
Sets the color ramp used for the gradient fill.
QString svgFilePath() const
Returns the path to the SVG file used to render the fill.
QColor strokeColor() const override
Gets stroke color.
void setOutputUnit(QgsUnitTypes::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
static Qt::BrushStyle decodeBrushStyle(const QString &str)
static QDomElement createVendorOptionElement(QDomDocument &doc, const QString &name, const QString &value)
QgsSVGFillSymbolLayer(const QString &svgFilePath, double width=20, double rotation=0.0)
Constructor for QgsSVGFillSymbolLayer, using the SVG picture at the specified absolute file path...
#define DEFAULT_SIMPLEFILL_JOINSTYLE
static QgsSymbolLayer * create(const QgsStringMap &properties=QgsStringMap())
Gradient reference point 1 x.
QByteArray getImageData(const QString &path) const
Gets image data.
QgsFields fields() const
Fields of the layer.
QgsMapUnitScale mStrokeWidthMapUnitScale
static QgsSymbolLayer * create(const QgsStringMap &properties=QgsStringMap())
Creates a new QgsRasterFillSymbolLayer from a properties map.
QgsRasterFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
Qt::PenStyle mStrokeStyle
void stopRender(QgsSymbolRenderContext &context) override
void setSvgFillColor(const QColor &c)
Sets the fill color used for rendering the SVG content.
void setOutputUnit(QgsUnitTypes::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QString layerType() const override
Returns a string that represents this layer type.
Abstract base class for all rendered symbols.
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...
void setColor(const QColor &c) override
The fill color.
QString imageFilePath() const
The path to the raster image used for the fill.
QPointF offset() const
Returns the offset for the shapeburst fill.
Use antialiasing while drawing.
QString readPath(const QString &filename) const
Turn filename read from the project file to an absolute path.
QgsMapUnitScale mapUnitScale() const override
void toSld(QDomDocument &doc, QDomElement &element, const QgsStringMap &props) const override
GradientCoordinateMode coordinateMode() const
Coordinate mode for gradient. Controls how the gradient stops are positioned.
QImage svgAsImage(const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth, double widthScaleFactor, bool &fitsInCache, double fixedAspectRatio=0)
Gets SVG as QImage.
QColor dxfColor(QgsSymbolRenderContext &context) const override
Gets color.
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
virtual QgsColorRamp * clone() const =0
Creates a clone of the color ramp.
void startRender(QgsSymbolRenderContext &context) override
void stopRender(QgsSymbolRenderContext &context) override
QgsPointPatternFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
Qt::PenJoinStyle penJoinStyle() const
GradientSpread gradientSpread() const
Gradient spread mode. Controls how the gradient behaves outside of the predefined stops...
A symbol fill consisting of repeated parallel lines.
QgsLinePatternFillSymbolLayer()
QgsUnitTypes::RenderUnit mOffsetUnit
QgsMapUnitScale mapUnitScale() const override
Base class for polygon renderers generating texture images.
void setColorRamp(QgsColorRamp *ramp)
Sets the color ramp used to draw the shapeburst fill.
void startRender(QgsSymbolRenderContext &context) override
static QgsImageCache * imageCache()
Returns the application's image cache, used for caching resampled versions of raster images...
void stopRender(QgsSymbolRenderContext &context) override
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer's subsymbol. takes ownership of the passed symbol.
void applyDataDefinedSettings(QgsSymbolRenderContext &context) override
QgsUnitTypes::RenderUnit patternWidthUnit() const
Returns the units for the width of the SVG images in the pattern.
bool hasDataDefinedProperties() const override
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties...
void startRender(QgsSymbolRenderContext &context) override
Abstract base class for color ramps.
static QString ogrFeatureStyleBrush(const QColor &fillColr)
Create ogr feature style string for brush.
QString ogrFeatureStyle(double mmScaleFactor, double mapUnitScaleFactor) const override
void setRendererScale(double scale)
Sets the renderer map scale.
void renderPolygon(const QPolygonF &points, QList< QPolygonF > *rings, QgsSymbolRenderContext &context) override
virtual QColor strokeColor() const
Gets stroke color.
void toSld(QDomDocument &doc, QDomElement &element, const QgsStringMap &props) const override
static bool displacementFromSldElement(QDomElement &element, QPointF &offset)
static QPointF decodePoint(const QString &string)
Decodes a QSizeF from a string.
QString layerType() const override
Returns a string that represents this layer type.
static QgsSymbolLayer * create(const QgsStringMap &properties=QgsStringMap())
Creates a new QgsLinePatternFillSymbolLayer from a properties map.
ShapeburstColorType colorType() const
Returns the color mode used for the shapeburst fill.
void copyPaintEffect(QgsSymbolLayer *destLayer) const
Copies paint effect of this layer to another symbol layer.
bool hasDataDefinedProperties() const override
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties...
void setOutputUnit(QgsUnitTypes::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QgsMapUnitScale mapUnitScale() const override
void setOutputUnit(QgsUnitTypes::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
~QgsGradientFillSymbolLayer() override
static QString encodeMapUnitScale(const QgsMapUnitScale &mapUnitScale)
static void createDisplacementElement(QDomDocument &doc, QDomElement &element, QPointF offset)
A geometry is the spatial representation of a feature.
void restoreOldDataDefinedProperties(const QgsStringMap &stringMap)
Restores older data defined properties from string map.
static double sizeInPixelsFromSldUom(const QString &uom, double size)
Returns the size scaled in pixels according to the uom attribute.
static QgsSymbolLayer * create(const QgsStringMap &properties=QgsStringMap())
Creates a new QgsSVGFillSymbolLayer from a properties map.
void _renderPolygon(QPainter *p, const QPolygonF &points, const QList< QPolygonF > *rings, QgsSymbolRenderContext &context)
Default method to render polygon.
bool useWholeShape() const
Returns whether the shapeburst fill is set to cover the entire shape.
Flags flags() const
Returns combination of flags used for rendering.
static QgsSymbolLayer * createFromSld(QDomElement &element)
int symbolLayerCount() const
Returns the total number of symbol layers contained in the symbol.
static QgsColorRamp * create(const QgsStringMap &properties=QgsStringMap())
#define DEFAULT_SIMPLEFILL_COLOR
QgsUnitTypes::DistanceUnit mapUnits() const
Retrieve map units.
void renderPolygon(const QPolygonF &points, QList< QPolygonF > *rings, QgsSymbolRenderContext &context) override
void startRender(QgsSymbolRenderContext &context) override
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
static bool rotationFromSldElement(QDomElement &element, QString &rotationFunc)
QColor color2() const
Color for endpoint of gradient, only used if the gradient color type is set to SimpleTwoColor.
QgsGradientFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
GradientColorType mGradientColorType
const QgsMapUnitScale & svgStrokeWidthMapUnitScale() const
Returns the map unit scale for the pattern's stroke.
virtual QColor color(double value) const =0
Returns the color corresponding to a specified value.
QColor color() const override
The fill color.
QgsMapUnitScale mDistanceYMapUnitScale
QPointF referencePoint1() const
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer's subsymbol. takes ownership of the passed symbol.
QString layerType() const override
Returns a string that represents this layer type.
QgsStringMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
QMap< QString, QString > QgsStringMap
Shapeburst use whole shape.
static QString encodePoint(QPointF point)
Encodes a QPointF to a string.
static QgsSymbolLayer * createFromSld(QDomElement &element)
Creates a new QgsSVGFillSymbolLayer from a SLD element.
QgsStringMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
A marker symbol type, for rendering Point and MultiPoint geometries.
QColor color() const override
The fill color.
static Qt::PenJoinStyle decodePenJoinStyle(const QString &str)
A line symbol type, for rendering LineString and MultiLineString geometries.
void startRender(QgsRenderContext &context, const QgsFields &fields=QgsFields())
Begins the rendering process for the symbol.
QgsUnitTypes::RenderUnit mStrokeWidthUnit
Gradient reference point 2 y.
double lineAngle() const
Returns the angle for the parallel lines used to fill the symbol.
bool isActive(int key) const override
Returns true if the collection contains an active property with the specified key.
QgsStringMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
QgsMapUnitScale mapUnitScale() const override
QgsUnitTypes::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
void setInterval(double interval)
Sets the interval between individual markers.
void setMapUnitScale(const QgsMapUnitScale &scale) override
#define DEFAULT_SIMPLEFILL_STYLE
static QString encodeColor(const QColor &color)
QgsMapUnitScale mDisplacementYMapUnitScale
void setCoordinateMode(FillCoordinateMode mode)
Set the coordinate mode for fill.
virtual bool hasDataDefinedProperties() const
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties...
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer's subsymbol. takes ownership of the passed symbol.
void setOutputUnit(QgsUnitTypes::RenderUnit unit)
Sets the units to use for sizes and widths within the symbol.
void setOffset(QPointF offset)
void setOutputUnit(QgsUnitTypes::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
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
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...
QPointF referencePoint2() const
QVariant value(int key, const QgsExpressionContext &context, const QVariant &defaultValue=QVariant()) const override
Returns the calculated value of the property with the specified key from within the collection...
void renderPoint(QPointF point, const QgsFeature *f, QgsRenderContext &context, int layer=-1, bool selected=false)
QString layerType() const override
Returns a string that represents this layer type.
QgsUnitTypes::RenderUnit mOffsetUnit
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for data defined symbology.
static QString encodePenStyle(Qt::PenStyle style)
Perform transforms between map coordinates and device coordinates.
double offset() const
Returns the offset distance for lines within the fill, which is the distance to offset the parallel l...
virtual void writeSldMarker(QDomDocument &doc, QDomElement &element, const QgsStringMap &props) const
Writes the symbol layer definition as a SLD XML element.
static QString svgSymbolPathToName(const QString &path, const QgsPathResolver &pathResolver)
Determines an SVG symbol's name from its path.
QgsUnitTypes::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
static double rescaleUom(double size, QgsUnitTypes::RenderUnit unit, const QgsStringMap &props)
Rescales the given size based on the uomScale found in the props, if any is found, otherwise returns the value un-modified.
QgsLinePatternFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
void setImageFilePath(const QString &imagePath)
Sets the path to the raster image used for the fill.
double strokeWidth() const
double dxfWidth(const QgsDxfExport &e, QgsSymbolRenderContext &context) const override
Gets line width.
std::unique_ptr< QgsLineSymbol > mStroke
Custom stroke.
virtual bool setSubSymbol(QgsSymbol *symbol)
Sets layer's subsymbol. takes ownership of the passed symbol.
A class for filling symbols with a repeated raster image.
QgsUnitTypes::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
QgsMapUnitScale mDistanceXMapUnitScale
#define DEFAULT_SIMPLEFILL_BORDERWIDTH
QColor dxfBrushColor(QgsSymbolRenderContext &context) const override
Gets brush/fill color.
void setScaleFactor(double factor)
Sets the scaling factor for the render to convert painter units to physical sizes.
QgsStringMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
static const bool SELECT_FILL_STYLE
Whether fill styles for selected features uses symbol layer style.
void setColor(const QColor &color) override
The fill color.
GradientType mGradientType
void setWidth(double width)
Sets the width for the whole line symbol.
qreal opacity() const
Returns the opacity for the symbol.
static QgsSymbolLayer * createFromSld(QDomElement &element)
double width() const
Returns the estimated width for the whole symbol, which is the maximum width of all marker symbol lay...
double dxfWidth(const QgsDxfExport &e, QgsSymbolRenderContext &context) const override
Gets line width.
void toSld(QDomDocument &doc, QDomElement &element, const QgsStringMap &props) const override
Gradient coordinate mode.
bool mReferencePoint1IsCentroid
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
QgsUnitTypes::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
static QgsSymbolLayer * create(const QgsStringMap &properties=QgsStringMap())
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the symbol layer's property collection, used for data defined overrides...
double displacementX() const
static QgsSymbolLayer * create(const QgsStringMap &properties=QgsStringMap())
static double mapUnitScaleFactor(double scale, QgsUnitTypes::RenderUnit symbolUnits, QgsUnitTypes::DistanceUnit mapUnits, double mapUnitsPerPixel=1.0)
Returns scale factor for conversion to map units.
virtual QColor color() const
The fill color.
static void resolvePaths(QgsStringMap &properties, const QgsPathResolver &pathResolver, bool saving)
Turns relative paths in properties map to absolute when reading and vice versa when writing...
static QgsSymbolLayer * createMarkerLayerFromSld(QDomElement &element)
static void createRotationElement(QDomDocument &doc, QDomElement &element, const QString &rotationFunc)
void renderPolygon(const QPolygonF &points, QList< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Filename, eg for svg files.
QColor selectionColor() const
QgsGradientFillSymbolLayer(const QColor &color=DEFAULT_SIMPLEFILL_COLOR, const QColor &color2=Qt::white, GradientColorType gradientColorType=SimpleTwoColor, GradientType gradientType=Linear, GradientCoordinateMode coordinateMode=Feature, GradientSpread gradientSpread=Pad)
void toSld(QDomDocument &doc, QDomElement &element, const QgsStringMap &props) const override
void startRender(QgsSymbolRenderContext &context) override
QList< QgsSymbolLayer * > QgsSymbolLayerList
void setPainter(QPainter *p)
Sets the destination QPainter for the render operation.
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
QColor color() const
Returns the symbol's color.
Shapeburst fill from edge distance.
void setMapUnitScale(const QgsMapUnitScale &scale) override
QgsSymbol::SymbolType type() const
bool ignoreRings() const
Returns whether the shapeburst fill is set to ignore polygon interior rings.
virtual double area() const
Returns the area of the geometry.
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...
QgsStringMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
virtual QString type() const =0
Returns a string representing the color ramp type.
QString layerType() const override
Returns a string that represents this layer type.
static Q_INVOKABLE QgsUnitTypes::RenderUnit decodeRenderUnit(const QString &string, bool *ok=nullptr)
Decodes a render unit from a string.
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)
void stopRender(QgsSymbolRenderContext &context) override
double mapUnitsPerPixel() const
Returns current map units per pixel.
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer's subsymbol. takes ownership of the passed symbol.
QColor fillColor() const override
Gets fill color.
QgsUnitTypes::RenderUnit svgStrokeWidthUnit() const
Returns the units for the stroke width.
QColor svgStrokeColor() const
Returns the stroke color used for rendering the SVG content.
QgsMapUnitScale mDisplacementXMapUnitScale
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
QgsRenderContext & renderContext()
Returns a reference to the context's render context.
void stopRender(QgsSymbolRenderContext &context) override
QColor color() const override
The fill color.
Tiling is based on feature bounding box.
QgsSymbolLayer * symbolLayer(int layer)
Returns a specific symbol layer contained in the symbol.
QgsSymbol * subSymbol() override
Returns the symbol's sub symbol, if present.
static Qt::PenStyle decodePenStyle(const QString &str)
static bool externalGraphicFromSld(QDomElement &element, QString &path, QString &mime, QColor &color, double &size)
bool mReferencePoint2IsCentroid
static void premultiplyColor(QColor &rgb, int alpha)
Converts a QColor into a premultiplied ARGB QColor value using a specified alpha value.
static void resolvePaths(QgsStringMap &properties, const QgsPathResolver &pathResolver, bool saving)
Turns relative paths in properties map to absolute when reading and vice versa when writing...
void applyDataDefinedSettings(QgsSymbolRenderContext &context) override
virtual double estimateMaxBleed(const QgsRenderContext &context) const
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
static bool fillFromSld(QDomElement &element, Qt::BrushStyle &brushStyle, QColor &color)
double lineWidth() const
Returns the width of the line subsymbol used to render the parallel lines in the fill.
QgsStringMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
QgsShapeburstFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
Gradient reference point 1 y.
~QgsPointPatternFillSymbolLayer() override
QgsStringMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
QgsMapUnitScale mapUnitScale() const override
static void createGeometryElement(QDomDocument &doc, QDomElement &element, const QString &geomFunc)
QgsMapUnitScale mapUnitScale() const override
double dxfAngle(QgsSymbolRenderContext &context) const override
Gets angle.
static Q_INVOKABLE QString encodeUnit(QgsUnitTypes::DistanceUnit unit)
Encodes a distance unit to a string.
void setMapUnitScale(const QgsMapUnitScale &scale) override
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
QgsExpressionContext & expressionContext()
Gets the expression context.
void containsParams(const QString &path, bool &hasFillParam, QColor &defaultFillColor, bool &hasStrokeParam, QColor &defaultStrokeColor, bool &hasStrokeWidthParam, double &defaultStrokeWidth) const
Tests if an svg file contains parameters for fill, stroke color, stroke width.
QString layerType() const override
Returns a string that represents this layer type.
void startRender(QgsSymbolRenderContext &context) override
void renderPolygon(const QPolygonF &points, QList< QPolygonF > *rings, QgsSymbolRenderContext &context) override
QString layerType() const override
Returns a string that represents this layer type.
void setOutputUnit(QgsUnitTypes::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
int geometryPartNum() const
Part number of current geometry.
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...
GradientCoordinateMode mCoordinateMode
GradientType gradientType() const
Type of gradient, e.g., linear or radial.
QgsRasterFillSymbolLayer(const QString &imageFilePath=QString())
Constructor for QgsRasterFillSymbolLayer, using a raster fill from the specified imageFilePath.
GradientSpread mGradientSpread
void setLineWidth(double w)
Sets the width of the line subsymbol used to render the parallel lines in the fill.
void setMapUnitScale(const QgsMapUnitScale &scale) override
static QPointF polygonCentroid(const QPolygonF &points)
Calculate the centroid point of a QPolygonF.
QgsUnitTypes::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
static QgsColorRamp * create(const QgsStringMap &properties=QgsStringMap())
Creates a new QgsColorRamp from a map of properties.
QgsUnitTypes::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
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...
A class for filling symbols with a repeated SVG file.
void setMapUnitScale(const QgsMapUnitScale &scale) override
Stroke style (eg solid, dashed)
QgsSymbol * subSymbol() override
Returns the symbol's sub symbol, if present.
QSet< QString > usedAttributes(const QgsRenderContext &context) const
Returns a list of attributes required to render this feature.
virtual QSet< QString > usedAttributes(const QgsRenderContext &context) const
Returns the set of attributes referenced by the layer.
Contains information about the context of a rendering operation.
Abstract base class for marker symbol layers.
double convertToPainterUnits(double size, QgsUnitTypes::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale()) const
Converts a size from the specified units to painter units (pixels).
QString layerType() const override
Returns a string that represents this layer type.
QgsCentroidFillSymbolLayer()
QgsCentroidFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
QPainter * painter()
Returns the destination QPainter for the render operation.
const QgsMapToPixel & mapToPixel() const
Qt::BrushStyle dxfBrushStyle() const override
Gets brush/fill style.
static QgsSymbolLayer * create(const QgsStringMap &properties=QgsStringMap())
static void blurImageInPlace(QImage &image, QRect rect, int radius, bool alphaOnly)
Blurs an image in place, e.g. creating Qt-independent drop shadows.
void setOutputUnit(QgsUnitTypes::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
bool hasDataDefinedProperties() const
Returns whether the symbol utilizes any data defined properties.
QgsPointPatternFillSymbolLayer()
QColor svgFillColor() const
Returns the fill color used for rendering the SVG content.
static QgsSymbolLayer * create(const QgsStringMap &properties=QgsStringMap())
QImage pathAsImage(const QString &path, const QSize size, const bool keepAspectRatio, const double opacity, bool &fitsInCache)
Returns the specified path rendered as an image.
SymbolType type() const
Returns the symbol's type.
~QgsShapeburstFillSymbolLayer() override
Struct for storing maximum and minimum scales for measurements in map units.
static QString encodeBrushStyle(Qt::BrushStyle style)
const QgsMapUnitScale & patternWidthMapUnitScale() const
Returns the map unit scale for the pattern's width.
void applyDataDefinedSettings(QgsSymbolRenderContext &context) override
void toSld(QDomDocument &doc, QDomElement &element, const QgsStringMap &props) const override
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
void setSvgFilePath(const QString &svgPath)
Sets the path to the SVG file to render in the fill.
virtual QgsStringMap properties() const =0
Returns a string map containing all the color ramp's properties.
QString ogrFeatureStyleWidth(double widthScaleFactor) const
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer's subsymbol. takes ownership of the passed symbol.
Qt::PenStyle strokeStyle() const
static const bool SELECTION_IS_OPAQUE
Whether styles for selected features ignore symbol alpha.
const QgsFeature * feature() const
Current feature being rendered - may be null.
#define DEFAULT_SIMPLEFILL_BORDERSTYLE
const QgsAbstractGeometry * geometryN(int n) const
Returns a const reference to a geometry from within the collection.
GradientColorType gradientColorType() const
Gradient color mode, controls how gradient color stops are created.
Qt::PenJoinStyle mPenJoinStyle
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
void setMapToPixel(const QgsMapToPixel &mtp)
QgsColorRamp * mGradientRamp
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.
double patternWidth() const
Returns the width of the rendered SVG content within the fill (i.e.
static QgsSymbolLayer * createFromSld(QDomElement &element)
Creates a new QgsLinePatternFillSymbolLayer from a SLD element.
Secondary color (eg for gradient fills)
static bool wellKnownMarkerFromSld(QDomElement &element, QString &name, QColor &color, QColor &strokeColor, Qt::PenStyle &strokeStyle, double &strokeWidth, double &size)
QgsMarkerSymbol * mMarkerSymbol
double maxDistance() const
Returns the maximum distance from the shape's boundary which is shaded.
QString writePath(const QString &filename) const
Prepare a filename to save it to the project file.
void applyDataDefinedSettings(QgsSymbolRenderContext &context) override
void setFlag(Flag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected)
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
double opacity() const
Returns the opacity for the raster image used in the fill.
static QgsMapUnitScale decodeMapUnitScale(const QString &str)
static QgsSymbolLayer * createLineLayerFromSld(QDomElement &element)
void setMapUnitScale(const QgsMapUnitScale &scale) override
static const bool SELECT_FILL_BORDER
Whether fill styles for selected features also highlight symbol stroke.
void setOutputUnit(QgsUnitTypes::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
void renderPolygon(const QPolygonF &points, QList< QPolygonF > *rings, QgsSymbolRenderContext &context) override
void setMapUnitScale(const QgsMapUnitScale &scale) override
static void fillToSld(QDomDocument &doc, QDomElement &element, Qt::BrushStyle brushStyle, const QColor &color=QColor())
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)
void setColor(const QColor &c) override
The fill color.
Qt::PenStyle dxfPenStyle() const override
Gets pen style.
double svgStrokeWidth() const
Returns the stroke width used for rendering the SVG content.
static QString svgSymbolNameToPath(const QString &name, const QgsPathResolver &pathResolver)
Determines an SVG symbol's path from its name.
QgsUnitTypes::RenderUnit mDistanceXUnit
int blurRadius() const
Returns the blur radius, which controls the amount of blurring applied to the fill.
bool testFlag(Flag flag) const
Check whether a particular flag is enabled.
static QPointF polygonPointOnSurface(const QPolygonF &points)
Calculate a point within of a QPolygonF.
QgsUnitTypes::RenderUnit mDisplacementYUnit
void stopRender(QgsSymbolRenderContext &context) override
Resolves relative paths into absolute paths and vice versa.
Draw map such that there are no problems between adjacent tiles.
void setOpacity(double opacity)
Sets the opacity for the raster image used in the fill.
void startRender(QgsSymbolRenderContext &context) override
void addStopsToGradient(QGradient *gradient, double opacity=1)
Copy color ramp stops to a QGradient.
double distance() const
Returns the distance between lines in the fill pattern.
void stopRender(QgsSymbolRenderContext &context) override
Gradient color ramp, which smoothly interpolates between two colors and also supports optional extra ...
void renderPolygon(const QPolygonF &points, QList< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Fill style (eg solid, dots)
double scaleFactor() const
Returns the scaling factor for the render to convert painter units to physical sizes.
double displacementY() const
virtual QColor fillColor() const
Gets fill 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...
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 void multiplyImageOpacity(QImage *image, qreal opacity)
Multiplies opacity of image pixel values with a (global) transparency value.
void stopRender(QgsRenderContext &context)
Ends the rendering process.
double width() const
Returns the width used for scaling the image used in the fill.
QgsUnitTypes::RenderUnit intervalUnit() const
Returns the units for the interval between markers.
QgsSVGFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
Gradient reference point 2 is centroid.
FillCoordinateMode
Fill coordinate modes, dictates fill tiling behavior.
void setMapUnitScale(const QgsMapUnitScale &scale) override
QgsShapeburstFillSymbolLayer(const QColor &color=DEFAULT_SIMPLEFILL_COLOR, const QColor &color2=Qt::white, ShapeburstColorType colorType=SimpleTwoColor, int blurRadius=0, bool useWholeShape=true, double maxDistance=5)
QgsMapUnitScale mOffsetMapUnitScale
static QString encodePenJoinStyle(Qt::PenJoinStyle style)
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
Gradient reference point 2 x.
QgsPropertyCollection mDataDefinedProperties
QgsUnitTypes::RenderUnit mDistanceYUnit
void startRender(QgsSymbolRenderContext &context) override
int geometryPartCount() const
Part count of current geometry.
Qt::PenStyle dxfPenStyle() const override
Gets pen style.
QgsMarkerSymbol * clone() const override
Returns a deep copy of this symbol.
~QgsLinePatternFillSymbolLayer() override
RenderUnit
Rendering size units.
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
static QColor decodeColor(const QString &str)
void copyDataDefinedProperties(QgsSymbolLayer *destLayer) const
Copies all data defined properties of this layer to another symbol layer.
QgsMapUnitScale mStrokeWidthMapUnitScale
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
QgsLineSymbol * clone() const override
Returns a deep copy of this symbol.
Horizontal distance between points.
QPointF offset() const
Returns the offset for the fill.
virtual QString layerType() const =0
Returns a string that represents this layer type.
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
void setColor(const QColor &color)
Sets the color for the symbol.
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
Vertical distance between points.
QgsMapUnitScale mOffsetMapUnitScale