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" );
275 selColor.setAlphaF( context.
opacity() );
334 if (
mBrush.style() == Qt::SolidPattern ||
mBrush.style() == Qt::NoBrush || !
dynamic_cast<QPagedPaintDevice *
>( p->device() ) )
346 p->setPen( Qt::NoPen );
350 p->setBrush( Qt::NoBrush );
367 map[QStringLiteral(
"outline_width" )] = QString::number(
mStrokeWidth );
395 QDomElement symbolizerElem = doc.createElement( QStringLiteral(
"se:PolygonSymbolizer" ) );
396 if ( !props.value( QStringLiteral(
"uom" ), QString() ).toString().isEmpty() )
397 symbolizerElem.setAttribute( QStringLiteral(
"uom" ), props.value( QStringLiteral(
"uom" ), QString() ).toString() );
398 element.appendChild( symbolizerElem );
407 bool exportOk {
false };
411 if ( ! image.isNull() )
414 QDomElement fillElem = doc.createElement( QStringLiteral(
"se:Fill" ) );
415 symbolizerElem.appendChild( fillElem );
416 QDomElement graphicFillElem = doc.createElement( QStringLiteral(
"se:GraphicFill" ) );
417 fillElem.appendChild( graphicFillElem );
418 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
419 graphicFillElem.appendChild( graphicElem );
421 const QFileInfo info { context.exportFilePath() };
422 QString pngPath { info.completeSuffix().isEmpty() ? context.exportFilePath() : context.exportFilePath().chopped( info.completeSuffix().length() ).append( QStringLiteral(
"png" ) ) };
424 image.save( pngPath );
439 const double alpha { props.value( QStringLiteral(
"alpha" ), QVariant() ).toDouble( &ok ) };
445 QDomElement fillElem = doc.createElement( QStringLiteral(
"se:Fill" ) );
446 symbolizerElem.appendChild( fillElem );
453 QDomElement strokeElem = doc.createElement( QStringLiteral(
"se:Stroke" ) );
454 symbolizerElem.appendChild( strokeElem );
458 const double alpha { props.value( QStringLiteral(
"alpha" ), QVariant() ).toDouble( &ok ) };
478 symbolStyle.append(
';' );
487 Qt::BrushStyle fillStyle;
491 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
494 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
500 double scaleFactor = 1.0;
501 const QString uom = element.attribute( QStringLiteral(
"uom" ) );
508 sl->setOutputUnit( sldUnitSize );
517 return penBleed + offsetBleed;
575 QPixmap pixmap( QSize( 32, 32 ) );
576 pixmap.fill( Qt::transparent );
578 painter.begin( &pixmap );
579 painter.setRenderHint( QPainter::Antialiasing );
587 std::unique_ptr< QgsSimpleFillSymbolLayer > layerClone(
clone() );
588 layerClone->setStrokeStyle( Qt::PenStyle::NoPen );
589 layerClone->drawPreviewIcon( symbolContext, pixmap.size() );
591 return pixmap.toImage();
599 : mGradientColorType( colorType )
600 , mGradientType( gradientType )
601 , mCoordinateMode( coordinateMode )
602 , mGradientSpread( spread )
603 , mReferencePoint1( QPointF( 0.5, 0 ) )
604 , mReferencePoint2( QPointF( 0.5, 1 ) )
625 bool refPoint1IsCentroid =
false;
627 bool refPoint2IsCentroid =
false;
632 if ( props.contains( QStringLiteral(
"type" ) ) )
634 if ( props.contains( QStringLiteral(
"coordinate_mode" ) ) )
636 if ( props.contains( QStringLiteral(
"spread" ) ) )
638 if ( props.contains( QStringLiteral(
"color_type" ) ) )
640 if ( props.contains( QStringLiteral(
"gradient_color" ) ) )
645 else if ( props.contains( QStringLiteral(
"color" ) ) )
649 if ( props.contains( QStringLiteral(
"gradient_color2" ) ) )
654 if ( props.contains( QStringLiteral(
"reference_point1" ) ) )
656 if ( props.contains( QStringLiteral(
"reference_point1_iscentroid" ) ) )
657 refPoint1IsCentroid = props[QStringLiteral(
"reference_point1_iscentroid" )].toInt();
658 if ( props.contains( QStringLiteral(
"reference_point2" ) ) )
660 if ( props.contains( QStringLiteral(
"reference_point2_iscentroid" ) ) )
661 refPoint2IsCentroid = props[QStringLiteral(
"reference_point2_iscentroid" )].toInt();
662 if ( props.contains( QStringLiteral(
"angle" ) ) )
663 angle = props[QStringLiteral(
"angle" )].toDouble();
665 if ( props.contains( QStringLiteral(
"offset" ) ) )
682 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
684 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
687 sl->setReferencePoint1IsCentroid( refPoint1IsCentroid );
689 sl->setReferencePoint2IsCentroid( refPoint2IsCentroid );
690 sl->setAngle(
angle );
692 sl->setColorRamp( gradientRamp );
694 sl->restoreOldDataDefinedProperties( props );
711 return QStringLiteral(
"GradientFill" );
714void QgsGradientFillSymbolLayer::applyDataDefinedSymbology(
QgsSymbolRenderContext &context,
const QPolygonF &points )
759 if ( currentType == QObject::tr(
"linear" ) )
763 else if ( currentType == QObject::tr(
"radial" ) )
767 else if ( currentType == QObject::tr(
"conical" ) )
781 if ( currentCoordMode == QObject::tr(
"feature" ) )
785 else if ( currentCoordMode == QObject::tr(
"viewport" ) )
799 if ( currentSpread == QObject::tr(
"pad" ) )
803 else if ( currentSpread == QObject::tr(
"repeat" ) )
807 else if ( currentSpread == QObject::tr(
"reflect" ) )
854 if ( refPoint1IsCentroid || refPoint2IsCentroid )
859 QRectF bbox = points.boundingRect();
860 double centroidX = ( centroid.x() - bbox.left() ) / bbox.width();
861 double centroidY = ( centroid.y() - bbox.top() ) / bbox.height();
863 if ( refPoint1IsCentroid )
865 refPoint1X = centroidX;
866 refPoint1Y = centroidY;
868 if ( refPoint2IsCentroid )
870 refPoint2X = centroidX;
871 refPoint2Y = centroidY;
877 spread, QPointF( refPoint1X, refPoint1Y ), QPointF( refPoint2X, refPoint2Y ),
angle );
880QPointF QgsGradientFillSymbolLayer::rotateReferencePoint( QPointF refPoint,
double angle )
885 QLineF refLine = QLineF( QPointF( 0.5, 0.5 ), refPoint );
887 refLine.setAngle( refLine.angle() +
angle );
889 QPointF rotatedReferencePoint = refLine.p2();
891 if ( rotatedReferencePoint.x() > 1 )
892 rotatedReferencePoint.setX( 1 );
893 if ( rotatedReferencePoint.x() < 0 )
894 rotatedReferencePoint.setX( 0 );
895 if ( rotatedReferencePoint.y() > 1 )
896 rotatedReferencePoint.setY( 1 );
897 if ( rotatedReferencePoint.y() < 0 )
898 rotatedReferencePoint.setY( 0 );
900 return rotatedReferencePoint;
907 QPointF referencePoint1, QPointF referencePoint2,
const double angle )
912 QColor fillColor2 =
color2;
913 fillColor2.setAlphaF( context.
opacity() * fillColor2.alphaF() );
924 gradient = QLinearGradient( rotatedReferencePoint1, rotatedReferencePoint2 );
927 gradient = QRadialGradient( rotatedReferencePoint1, QLineF( rotatedReferencePoint1, rotatedReferencePoint2 ).length() );
930 gradient = QConicalGradient( rotatedReferencePoint1, QLineF( rotatedReferencePoint1, rotatedReferencePoint2 ).
angle() );
936 gradient.setCoordinateMode( QGradient::ObjectBoundingMode );
939 gradient.setCoordinateMode( QGradient::StretchToDeviceMode );
945 gradient.setSpread( QGradient::PadSpread );
948 gradient.setSpread( QGradient::ReflectSpread );
951 gradient.setSpread( QGradient::RepeatSpread );
967 gradient.setColorAt( 1.0, fillColor2 );
971 brush = QBrush( gradient );
978 selColor.setAlphaF( context.
opacity() );
995 applyDataDefinedSymbology( context, points );
999 p->setPen( Qt::NoPen );
1032 map[QStringLiteral(
"color_type" )] = QString::number(
static_cast< int >(
mGradientColorType ) );
1033 map[QStringLiteral(
"type" )] = QString::number(
static_cast<int>(
mGradientType ) );
1034 map[QStringLiteral(
"coordinate_mode" )] = QString::number(
static_cast< int >(
mCoordinateMode ) );
1035 map[QStringLiteral(
"spread" )] = QString::number(
static_cast< int >(
mGradientSpread ) );
1040 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
1066 return sl.release();
1108 int blurRadius,
bool useWholeShape,
double maxDistance )
1109 : mBlurRadius( blurRadius )
1110 , mUseWholeShape( useWholeShape )
1111 , mMaxDistance( maxDistance )
1112 , mColorType( colorType )
1131 if ( props.contains( QStringLiteral(
"color_type" ) ) )
1135 if ( props.contains( QStringLiteral(
"shapeburst_color" ) ) )
1140 else if ( props.contains( QStringLiteral(
"color" ) ) )
1145 if ( props.contains( QStringLiteral(
"shapeburst_color2" ) ) )
1150 else if ( props.contains( QStringLiteral(
"gradient_color2" ) ) )
1154 if ( props.contains( QStringLiteral(
"blur_radius" ) ) )
1156 blurRadius = props[QStringLiteral(
"blur_radius" )].toInt();
1158 if ( props.contains( QStringLiteral(
"use_whole_shape" ) ) )
1160 useWholeShape = props[QStringLiteral(
"use_whole_shape" )].toInt();
1162 if ( props.contains( QStringLiteral(
"max_distance" ) ) )
1164 maxDistance = props[QStringLiteral(
"max_distance" )].toDouble();
1166 if ( props.contains( QStringLiteral(
"offset" ) ) )
1185 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
1189 if ( props.contains( QStringLiteral(
"distance_unit" ) ) )
1193 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
1197 if ( props.contains( QStringLiteral(
"distance_map_unit_scale" ) ) )
1201 if ( props.contains( QStringLiteral(
"ignore_rings" ) ) )
1203 sl->setIgnoreRings( props[QStringLiteral(
"ignore_rings" )].toInt() );
1207 sl->setColorRamp( gradientRamp );
1210 sl->restoreOldDataDefinedProperties( props );
1212 return sl.release();
1217 return QStringLiteral(
"ShapeburstFill" );
1227 if ( mGradientRamp.get() == ramp )
1230 mGradientRamp.reset( ramp );
1233void QgsShapeburstFillSymbolLayer::applyDataDefinedSymbology(
QgsSymbolRenderContext &context, QColor &color, QColor &color2,
int &blurRadius,
bool &useWholeShape,
1234 double &maxDistance,
bool &ignoreRings )
1291 selColor.setAlphaF( context.
opacity() );
1292 mSelBrush = QBrush( selColor );
1309 if ( useSelectedColor )
1312 p->setBrush( mSelBrush );
1313 QPointF
offset = mOffset;
1348 int outputPixelMaxDist = 0;
1356 std::unique_ptr< QgsGradientColorRamp > twoColorGradientRamp;
1359 twoColorGradientRamp = std::make_unique< QgsGradientColorRamp >( color1,
color2 );
1363 p->setPen( QPen( Qt::NoPen ) );
1368 int pointsWidth =
static_cast< int >( std::round( points.boundingRect().width() ) );
1369 int pointsHeight =
static_cast< int >( std::round( points.boundingRect().height() ) );
1370 int imWidth = pointsWidth + ( sideBuffer * 2 );
1371 int imHeight = pointsHeight + ( sideBuffer * 2 );
1377 auto fillImage = std::make_unique< QImage >( imWidth,
1378 imHeight, QImage::Format_ARGB32_Premultiplied );
1379 if ( fillImage->isNull() )
1389 auto alphaImage = std::make_unique< QImage >( fillImage->width(), fillImage->height(), QImage::Format_ARGB32_Premultiplied );
1390 if ( alphaImage->isNull() )
1402 fillImage->fill( Qt::black );
1408 alphaImage->fill( Qt::transparent );
1414 QPainter imgPainter;
1415 imgPainter.begin( alphaImage.get() );
1416 imgPainter.setRenderHint( QPainter::Antialiasing,
true );
1417 imgPainter.setBrush( QBrush( Qt::white ) );
1418 imgPainter.setPen( QPen( Qt::black ) );
1419 imgPainter.translate( -points.boundingRect().left() + sideBuffer, - points.boundingRect().top() + sideBuffer );
1428 imgPainter.begin( fillImage.get() );
1431 imgPainter.drawImage( 0, 0, *alphaImage );
1438 imgPainter.setBrush( QBrush( Qt::white ) );
1439 imgPainter.setPen( QPen( Qt::black ) );
1440 imgPainter.translate( -points.boundingRect().left() + sideBuffer, - points.boundingRect().top() + sideBuffer );
1449 double *dtArray = distanceTransform( fillImage.get(), context.
renderContext() );
1469 imgPainter.begin( fillImage.get() );
1470 imgPainter.setCompositionMode( QPainter::CompositionMode_DestinationIn );
1471 imgPainter.drawImage( 0, 0, *alphaImage );
1479 QPointF
offset = mOffset;
1496 p->drawImage( points.boundingRect().left() - sideBuffer, points.boundingRect().top() - sideBuffer, *fillImage );
1507void QgsShapeburstFillSymbolLayer::distanceTransform1d(
double *f,
int n,
int *v,
double *z,
double *d )
1513 for (
int q = 1; q <= n - 1; q++ )
1515 double s = ( ( f[q] +
static_cast< double >( q ) * q ) - ( f[v[k]] + (
static_cast< double >( v[k] ) * v[k] ) ) ) / ( 2 * q - 2 * v[k] );
1519 s = ( ( f[q] +
static_cast< double >( q ) * q ) - ( f[v[k]] + (
static_cast< double >( v[k] ) * v[k] ) ) ) / ( 2 * q - 2 * v[k] );
1528 for (
int q = 0; q <= n - 1; q++ )
1530 while ( z[k + 1] < q )
1532 d[q] =
static_cast< double >( q - v[k] ) * ( q - v[k] ) + f[v[k]];
1537void QgsShapeburstFillSymbolLayer::distanceTransform2d(
double *im,
int width,
int height,
QgsRenderContext &context )
1539 int maxDimension = std::max( width, height );
1540 double *f =
new double[ maxDimension ];
1541 int *v =
new int[ maxDimension ];
1542 double *z =
new double[ maxDimension + 1 ];
1543 double *d =
new double[ maxDimension ];
1546 for (
int x = 0; x < width; x++ )
1551 for (
int y = 0; y < height; y++ )
1553 f[y] = im[ x +
static_cast< std::size_t
>( y ) * width ];
1555 distanceTransform1d( f, height, v, z, d );
1556 for (
int y = 0; y < height; y++ )
1558 im[ x +
static_cast< std::size_t
>( y ) * width ] = d[y];
1563 for (
int y = 0; y < height; y++ )
1568 for (
int x = 0; x < width; x++ )
1570 f[x] = im[ x +
static_cast< std::size_t
>( y ) * width ];
1572 distanceTransform1d( f, width, v, z, d );
1573 for (
int x = 0; x < width; x++ )
1575 im[ x +
static_cast< std::size_t
>( y ) * width ] = d[x];
1586double *QgsShapeburstFillSymbolLayer::distanceTransform( QImage *im,
QgsRenderContext &context )
1588 int width = im->width();
1589 int height = im->height();
1591 double *dtArray =
new double[
static_cast< std::size_t
>( width ) * height];
1595 std::size_t idx = 0;
1596 for (
int heightIndex = 0; heightIndex < height; ++heightIndex )
1601 const QRgb *scanLine =
reinterpret_cast< const QRgb *
>( im->constScanLine( heightIndex ) );
1602 for (
int widthIndex = 0; widthIndex < width; ++widthIndex )
1604 tmpRgb = scanLine[widthIndex];
1605 if ( qRed( tmpRgb ) == 0 )
1613 dtArray[ idx ] =
INF;
1620 distanceTransform2d( dtArray, width, height, context );
1625void QgsShapeburstFillSymbolLayer::dtArrayToQImage(
double *array, QImage *im,
QgsColorRamp *ramp,
QgsRenderContext &context,
bool useWholeShape,
int maxPixelDistance )
1627 int width = im->width();
1628 int height = im->height();
1631 double maxDistanceValue;
1636 double dtMaxValue = array[0];
1637 for ( std::size_t i = 1; i < static_cast< std::size_t >( width ) * height; ++i )
1639 if ( array[i] > dtMaxValue )
1641 dtMaxValue = array[i];
1646 maxDistanceValue = std::sqrt( dtMaxValue );
1651 maxDistanceValue = maxPixelDistance;
1655 std::size_t idx = 0;
1656 double squaredVal = 0;
1659 for (
int heightIndex = 0; heightIndex < height; ++heightIndex )
1664 QRgb *scanLine =
reinterpret_cast< QRgb *
>( im->scanLine( heightIndex ) );
1665 for (
int widthIndex = 0; widthIndex < width; ++widthIndex )
1668 squaredVal = array[idx];
1671 if ( maxDistanceValue > 0 )
1673 pixVal = squaredVal > 0 ? std::min( ( std::sqrt( squaredVal ) / maxDistanceValue ), 1.0 ) : 0;
1682 scanLine[widthIndex] = qPremultiply( ramp->
color( pixVal ).rgba() );
1693 map[QStringLiteral(
"color_type" )] = QString::number(
static_cast< int >( mColorType ) );
1694 map[QStringLiteral(
"blur_radius" )] = QString::number( mBlurRadius );
1695 map[QStringLiteral(
"use_whole_shape" )] = QString::number( mUseWholeShape );
1696 map[QStringLiteral(
"max_distance" )] = QString::number( mMaxDistance );
1699 map[QStringLiteral(
"ignore_rings" )] = QString::number( mIgnoreRings );
1703 if ( mGradientRamp )
1705 map.insert( mGradientRamp->properties() );
1713 auto sl = std::make_unique< QgsShapeburstFillSymbolLayer >(
mColor, mColor2, mColorType, mBlurRadius, mUseWholeShape, mMaxDistance );
1714 if ( mGradientRamp )
1716 sl->setColorRamp( mGradientRamp->clone() );
1718 sl->setDistanceUnit( mDistanceUnit );
1719 sl->setDistanceMapUnitScale( mDistanceMapUnitScale );
1720 sl->setIgnoreRings( mIgnoreRings );
1721 sl->setOffset( mOffset );
1722 sl->setOffsetUnit( mOffsetUnit );
1723 sl->setOffsetMapUnitScale( mOffsetMapUnitScale );
1726 return sl.release();
1731 double offsetBleed = context.
convertToPainterUnits( std::max( std::fabs( mOffset.x() ), std::fabs( mOffset.y() ) ), mOffsetUnit, mOffsetMapUnitScale );
1742 mDistanceUnit = unit;
1748 if ( mDistanceUnit == mOffsetUnit )
1750 return mDistanceUnit;
1763 mDistanceMapUnitScale = scale;
1764 mOffsetMapUnitScale = scale;
1769 if ( mDistanceMapUnitScale == mOffsetMapUnitScale )
1771 return mDistanceMapUnitScale;
1796 p->setPen( QPen( Qt::NoPen ) );
1798 QTransform bkTransform =
mBrush.transform();
1802 QTransform t =
mBrush.transform();
1803 t.translate( leftCorner.x(), leftCorner.y() );
1804 mBrush.setTransform( t );
1808 QTransform t =
mBrush.transform();
1809 t.translate( 0, 0 );
1810 mBrush.setTransform( t );
1814 if ( useSelectedColor )
1817 p->setBrush( QBrush( selColor ) );
1823 QTransform t =
mBrush.transform();
1825 mBrush.setTransform( t );
1830 mBrush.setTransform( bkTransform );
1866 return Qt::SolidLine;
1870 return Qt::SolidLine;
1874 return mStroke->dxfPenStyle();
1910 , mPatternWidth( width )
1914 mColor = QColor( 255, 255, 255 );
1920 , mPatternWidth( width )
1921 , mSvgData( svgData )
1926 mColor = QColor( 255, 255, 255 );
1927 setDefaultSvgParams();
1935 mPatternWidthUnit = unit;
1936 mSvgStrokeWidthUnit = unit;
1939 mStroke->setOutputUnit( unit );
1945 if ( mPatternWidthUnit != unit || mSvgStrokeWidthUnit != unit ||
mStrokeWidthUnit != unit )
1955 mPatternWidthMapUnitScale = scale;
1956 mSvgStrokeWidthMapUnitScale = scale;
1962 mPatternWidthMapUnitScale == mSvgStrokeWidthMapUnitScale &&
1965 return mPatternWidthMapUnitScale;
1975 mSvgFilePath = svgPath;
1976 setDefaultSvgParams();
1986 if (
properties.contains( QStringLiteral(
"width" ) ) )
1988 width =
properties[QStringLiteral(
"width" )].toDouble();
1990 if (
properties.contains( QStringLiteral(
"svgFile" ) ) )
1994 if (
properties.contains( QStringLiteral(
"angle" ) ) )
1999 std::unique_ptr< QgsSVGFillSymbolLayer > symbolLayer;
2002 symbolLayer = std::make_unique< QgsSVGFillSymbolLayer >(
svgFilePath, width,
angle );
2006 if (
properties.contains( QStringLiteral(
"data" ) ) )
2008 data = QByteArray::fromHex(
properties[QStringLiteral(
"data" )].toString().toLocal8Bit() );
2010 symbolLayer = std::make_unique< QgsSVGFillSymbolLayer >( data, width,
angle );
2014 if (
properties.contains( QStringLiteral(
"svgFillColor" ) ) )
2019 else if (
properties.contains( QStringLiteral(
"color" ) ) )
2023 if (
properties.contains( QStringLiteral(
"svgOutlineColor" ) ) )
2028 else if (
properties.contains( QStringLiteral(
"outline_color" ) ) )
2032 else if (
properties.contains( QStringLiteral(
"line_color" ) ) )
2036 if (
properties.contains( QStringLiteral(
"svgOutlineWidth" ) ) )
2039 symbolLayer->setSvgStrokeWidth(
properties[QStringLiteral(
"svgOutlineWidth" )].toDouble() );
2041 else if (
properties.contains( QStringLiteral(
"outline_width" ) ) )
2043 symbolLayer->setSvgStrokeWidth(
properties[QStringLiteral(
"outline_width" )].toDouble() );
2045 else if (
properties.contains( QStringLiteral(
"line_width" ) ) )
2047 symbolLayer->setSvgStrokeWidth(
properties[QStringLiteral(
"line_width" )].toDouble() );
2051 if (
properties.contains( QStringLiteral(
"pattern_width_unit" ) ) )
2055 if (
properties.contains( QStringLiteral(
"pattern_width_map_unit_scale" ) ) )
2059 if (
properties.contains( QStringLiteral(
"svg_outline_width_unit" ) ) )
2063 if (
properties.contains( QStringLiteral(
"svg_outline_width_map_unit_scale" ) ) )
2067 if (
properties.contains( QStringLiteral(
"outline_width_unit" ) ) )
2071 if (
properties.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
2076 if (
properties.contains( QStringLiteral(
"parameters" ) ) )
2082 symbolLayer->restoreOldDataDefinedProperties(
properties );
2084 return symbolLayer.release();
2089 QVariantMap::iterator it =
properties.find( QStringLiteral(
"svgFile" ) );
2101 return QStringLiteral(
"SVGFill" );
2104void QgsSVGFillSymbolLayer::applyPattern( QBrush &brush,
const QString &svgFilePath,
double patternWidth,
Qgis::RenderUnit patternWidthUnit,
2105 const QColor &svgFillColor,
const QColor &svgStrokeColor,
double svgStrokeWidth,
2109 if ( mSvgViewBox.isNull() )
2116 if (
static_cast< int >( size ) < 1.0 || 10000.0 < size )
2118 brush.setTextureImage( QImage() );
2122 bool fitsInCache =
true;
2130 double hwRatio = 1.0;
2131 if ( patternPict.width() > 0 )
2133 hwRatio =
static_cast< double >( patternPict.height() ) /
static_cast< double >( patternPict.width() );
2135 patternImage = QImage(
static_cast< int >( size ),
static_cast< int >( size * hwRatio ), QImage::Format_ARGB32_Premultiplied );
2136 patternImage.fill( 0 );
2138 QPainter p( &patternImage );
2139 p.drawPicture( QPointF( size / 2, size * hwRatio / 2 ), patternPict );
2142 QTransform brushTransform;
2145 QImage transparentImage = patternImage.copy();
2147 brush.setTextureImage( transparentImage );
2151 brush.setTextureImage( patternImage );
2153 brush.setTransform( brushTransform );
2161 applyPattern(
mBrush, mSvgFilePath, mPatternWidth, mPatternWidthUnit,
mColor, mSvgStrokeColor, mSvgStrokeWidth, mSvgStrokeWidthUnit, context, mPatternWidthMapUnitScale, mSvgStrokeWidthMapUnitScale, evaluatedParameters );
2185 mStroke->renderPolyline( points, context.
feature(), context.
renderContext(), -1, useSelectedColor );
2188 for (
auto ringIt = rings->constBegin(); ringIt != rings->constEnd(); ++ringIt )
2190 mStroke->renderPolyline( *ringIt, context.
feature(), context.
renderContext(), -1, useSelectedColor );
2199 if ( !mSvgFilePath.isEmpty() )
2201 map.insert( QStringLiteral(
"svgFile" ), mSvgFilePath );
2205 map.insert( QStringLiteral(
"data" ), QString( mSvgData.toHex() ) );
2208 map.insert( QStringLiteral(
"width" ), QString::number( mPatternWidth ) );
2209 map.insert( QStringLiteral(
"angle" ), QString::number(
mAngle ) );
2214 map.insert( QStringLiteral(
"outline_width" ), QString::number( mSvgStrokeWidth ) );
2231 std::unique_ptr< QgsSVGFillSymbolLayer > clonedLayer;
2232 if ( !mSvgFilePath.isEmpty() )
2234 clonedLayer = std::make_unique< QgsSVGFillSymbolLayer >( mSvgFilePath, mPatternWidth,
mAngle );
2235 clonedLayer->setSvgFillColor(
mColor );
2236 clonedLayer->setSvgStrokeColor( mSvgStrokeColor );
2237 clonedLayer->setSvgStrokeWidth( mSvgStrokeWidth );
2241 clonedLayer = std::make_unique< QgsSVGFillSymbolLayer >( mSvgData, mPatternWidth,
mAngle );
2244 clonedLayer->setPatternWidthUnit( mPatternWidthUnit );
2245 clonedLayer->setPatternWidthMapUnitScale( mPatternWidthMapUnitScale );
2246 clonedLayer->setSvgStrokeWidthUnit( mSvgStrokeWidthUnit );
2247 clonedLayer->setSvgStrokeWidthMapUnitScale( mSvgStrokeWidthMapUnitScale );
2251 clonedLayer->setParameters( mParameters );
2255 clonedLayer->setSubSymbol( mStroke->clone() );
2259 return clonedLayer.release();
2264 QDomElement symbolizerElem = doc.createElement( QStringLiteral(
"se:PolygonSymbolizer" ) );
2265 if ( !props.value( QStringLiteral(
"uom" ), QString() ).toString().isEmpty() )
2266 symbolizerElem.setAttribute( QStringLiteral(
"uom" ), props.value( QStringLiteral(
"uom" ), QString() ).toString() );
2267 element.appendChild( symbolizerElem );
2271 QDomElement fillElem = doc.createElement( QStringLiteral(
"se:Fill" ) );
2272 symbolizerElem.appendChild( fillElem );
2274 QDomElement graphicFillElem = doc.createElement( QStringLiteral(
"se:GraphicFill" ) );
2275 fillElem.appendChild( graphicFillElem );
2277 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
2278 graphicFillElem.appendChild( graphicElem );
2280 if ( !mSvgFilePath.isEmpty() )
2291 symbolizerElem.appendChild( doc.createComment( QStringLiteral(
"SVG from data not implemented yet" ) ) );
2297 double angle = props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toDouble( &ok );
2300 angleFunc = QStringLiteral(
"%1 + %2" ).arg( props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toString() ).arg(
mAngle );
2313 mStroke->toSld( doc, element, props );
2325 return mStroke.get();
2332 mStroke.reset(
nullptr );
2345 mStroke.reset( lineSymbol );
2355 if ( mStroke && mStroke->symbolLayer( 0 ) )
2357 double subLayerBleed = mStroke->symbolLayer( 0 )->estimateMaxBleed( context );
2358 return subLayerBleed;
2368 return QColor( Qt::black );
2370 return mStroke->color();
2377 attr.unite( mStroke->usedAttributes( context ) );
2385 if ( mStroke && mStroke->hasDataDefinedProperties() )
2392 QString path, mimeType;
2394 Qt::PenStyle penStyle;
2395 double size, strokeWidth;
2397 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
2398 if ( fillElem.isNull() )
2401 QDomElement graphicFillElem = fillElem.firstChildElement( QStringLiteral(
"GraphicFill" ) );
2402 if ( graphicFillElem.isNull() )
2405 QDomElement graphicElem = graphicFillElem.firstChildElement( QStringLiteral(
"Graphic" ) );
2406 if ( graphicElem.isNull() )
2412 if ( mimeType != QLatin1String(
"image/svg+xml" ) )
2417 double scaleFactor = 1.0;
2418 const QString uom = element.attribute( QStringLiteral(
"uom" ) );
2420 size = size * scaleFactor;
2421 strokeWidth = strokeWidth * scaleFactor;
2428 double d = angleFunc.toDouble( &ok );
2433 auto sl = std::make_unique< QgsSVGFillSymbolLayer >( path, size,
angle );
2434 sl->setOutputUnit( sldUnitSize );
2437 sl->setSvgStrokeWidth( strokeWidth );
2440 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
2441 if ( !strokeElem.isNull() )
2447 layers.append( l.release() );
2452 return sl.release();
2470 double width = mPatternWidth;
2476 QString svgFile = mSvgFilePath;
2495 double strokeWidth = mSvgStrokeWidth;
2504 mSvgStrokeWidthUnit, context, mPatternWidthMapUnitScale, mSvgStrokeWidthMapUnitScale, evaluatedParameters );
2508void QgsSVGFillSymbolLayer::storeViewBox()
2510 if ( !mSvgData.isEmpty() )
2512 QSvgRenderer r( mSvgData );
2515 mSvgViewBox = r.viewBoxF();
2520 mSvgViewBox = QRectF();
2523void QgsSVGFillSymbolLayer::setDefaultSvgParams()
2525 if ( mSvgFilePath.isEmpty() )
2530 bool hasFillParam, hasFillOpacityParam, hasStrokeParam, hasStrokeWidthParam, hasStrokeOpacityParam;
2531 bool hasDefaultFillColor, hasDefaultFillOpacity, hasDefaultStrokeColor, hasDefaultStrokeWidth, hasDefaultStrokeOpacity;
2532 QColor defaultFillColor, defaultStrokeColor;
2533 double defaultStrokeWidth, defaultFillOpacity, defaultStrokeOpacity;
2535 hasFillOpacityParam, hasDefaultFillOpacity, defaultFillOpacity,
2536 hasStrokeParam, hasDefaultStrokeColor, defaultStrokeColor,
2537 hasStrokeWidthParam, hasDefaultStrokeWidth, defaultStrokeWidth,
2538 hasStrokeOpacityParam, hasDefaultStrokeOpacity, defaultStrokeOpacity );
2540 double newFillOpacity = hasFillOpacityParam ?
mColor.alphaF() : 1.0;
2541 double newStrokeOpacity = hasStrokeOpacityParam ? mSvgStrokeColor.alphaF() : 1.0;
2543 if ( hasDefaultFillColor )
2545 mColor = defaultFillColor;
2546 mColor.setAlphaF( newFillOpacity );
2548 if ( hasDefaultFillOpacity )
2550 mColor.setAlphaF( defaultFillOpacity );
2552 if ( hasDefaultStrokeColor )
2554 mSvgStrokeColor = defaultStrokeColor;
2555 mSvgStrokeColor.setAlphaF( newStrokeOpacity );
2557 if ( hasDefaultStrokeOpacity )
2559 mSvgStrokeColor.setAlphaF( defaultStrokeOpacity );
2561 if ( hasDefaultStrokeWidth )
2563 mSvgStrokeWidth = defaultStrokeWidth;
2576 mFillLineSymbol = std::make_unique<QgsLineSymbol>( );
2584 mFillLineSymbol->setWidth( w );
2590 mFillLineSymbol->setColor(
c );
2596 return mFillLineSymbol ? mFillLineSymbol->color() :
mColor;
2608 mFillLineSymbol.reset( qgis::down_cast<QgsLineSymbol *>( symbol ) );
2617 return mFillLineSymbol.get();
2623 if ( mFillLineSymbol )
2624 attr.unite( mFillLineSymbol->usedAttributes( context ) );
2632 if ( mFillLineSymbol && mFillLineSymbol->hasDataDefinedProperties() )
2654 double lineAngleRad { qDegreesToRadians( mLineAngle ) };
2656 const int quadrant {
static_cast<int>( lineAngleRad / M_PI_2 ) };
2657 Q_ASSERT( quadrant >= 0 && quadrant <= 3 );
2667 lineAngleRad -= M_PI / 2;
2672 lineAngleRad -= M_PI;
2677 lineAngleRad -= M_PI + M_PI_2;
2685 QSize size {
static_cast<int>( distancePx ),
static_cast<int>( distancePx ) };
2687 if (
static_cast<int>( mLineAngle ) % 90 != 0 )
2689 size = QSize(
static_cast<int>( distancePx / std::sin( lineAngleRad ) ),
static_cast<int>( distancePx / std::cos( lineAngleRad ) ) );
2692 QPixmap pixmap( size );
2693 pixmap.fill( Qt::transparent );
2695 painter.begin( &pixmap );
2696 painter.setRenderHint( QPainter::Antialiasing );
2704 std::unique_ptr< QgsLinePatternFillSymbolLayer > layerClone(
clone() );
2705 layerClone->setOffset( 0 );
2706 layerClone->drawPreviewIcon( symbolContext, pixmap.size() );
2708 return pixmap.toImage();
2719 mDistanceUnit = unit;
2720 mLineWidthUnit = unit;
2723 if ( mFillLineSymbol )
2724 mFillLineSymbol->setOutputUnit( unit );
2747 mDistanceMapUnitScale = scale;
2748 mLineWidthMapUnitScale = scale;
2749 mOffsetMapUnitScale = scale;
2755 mDistanceMapUnitScale == mLineWidthMapUnitScale &&
2756 mLineWidthMapUnitScale == mOffsetMapUnitScale )
2758 return mDistanceMapUnitScale;
2765 auto patternLayer = std::make_unique< QgsLinePatternFillSymbolLayer >();
2771 QColor
color( Qt::black );
2774 if (
properties.contains( QStringLiteral(
"lineangle" ) ) )
2779 else if (
properties.contains( QStringLiteral(
"angle" ) ) )
2783 patternLayer->setLineAngle(
lineAngle );
2785 if (
properties.contains( QStringLiteral(
"distance" ) ) )
2789 patternLayer->setDistance(
distance );
2791 if (
properties.contains( QStringLiteral(
"linewidth" ) ) )
2796 else if (
properties.contains( QStringLiteral(
"outline_width" ) ) )
2800 else if (
properties.contains( QStringLiteral(
"line_width" ) ) )
2804 patternLayer->setLineWidth(
lineWidth );
2806 if (
properties.contains( QStringLiteral(
"color" ) ) )
2810 else if (
properties.contains( QStringLiteral(
"outline_color" ) ) )
2814 else if (
properties.contains( QStringLiteral(
"line_color" ) ) )
2818 patternLayer->setColor(
color );
2820 if (
properties.contains( QStringLiteral(
"offset" ) ) )
2824 patternLayer->setOffset(
offset );
2827 if (
properties.contains( QStringLiteral(
"distance_unit" ) ) )
2831 if (
properties.contains( QStringLiteral(
"distance_map_unit_scale" ) ) )
2835 if (
properties.contains( QStringLiteral(
"line_width_unit" ) ) )
2839 else if (
properties.contains( QStringLiteral(
"outline_width_unit" ) ) )
2843 if (
properties.contains( QStringLiteral(
"line_width_map_unit_scale" ) ) )
2847 if (
properties.contains( QStringLiteral(
"offset_unit" ) ) )
2851 if (
properties.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
2855 if (
properties.contains( QStringLiteral(
"outline_width_unit" ) ) )
2859 if (
properties.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
2863 if (
properties.contains( QStringLiteral(
"coordinate_reference" ) ) )
2867 if (
properties.contains( QStringLiteral(
"clip_mode" ) ) )
2872 patternLayer->restoreOldDataDefinedProperties(
properties );
2874 return patternLayer.release();
2879 return QStringLiteral(
"LinePatternFill" );
2882bool QgsLinePatternFillSymbolLayer::applyPattern(
const QgsSymbolRenderContext &context, QBrush &brush,
double lineAngle,
double distance )
2884 mBrush.setTextureImage( QImage() );
2886 if ( !mFillLineSymbol )
2891 std::unique_ptr< QgsLineSymbol > fillLineSymbol( mFillLineSymbol->clone() );
2892 if ( !fillLineSymbol )
2908 outputPixelOffset = std::fmod( outputPixelOffset, outputPixelDist );
2909 if ( outputPixelOffset > outputPixelDist / 2.0 )
2910 outputPixelOffset -= outputPixelDist;
2914 double outputPixelBleed = 0;
2915 double outputPixelInterval = 0;
2916 for (
int i = 0; i < fillLineSymbol->symbolLayerCount(); i++ )
2920 outputPixelBleed = std::max( outputPixelBleed, outputPixelLayerBleed );
2923 if ( markerLineLayer )
2932 outputPixelInterval = std::max( outputPixelInterval, outputPixelLayerInterval );
2936 if ( outputPixelInterval > 0 )
2940 double intervalScale = std::round( outputPixelInterval ) / outputPixelInterval;
2941 outputPixelInterval = std::round( outputPixelInterval );
2943 for (
int i = 0; i < fillLineSymbol->symbolLayerCount(); i++ )
2948 if ( markerLineLayer )
2962 height = outputPixelDist;
2963 width = outputPixelInterval > 0 ? outputPixelInterval : height;
2967 width = outputPixelDist;
2968 height = outputPixelInterval > 0 ? outputPixelInterval : width;
2972 height = outputPixelDist / std::cos(
lineAngle * M_PI / 180 );
2973 width = outputPixelDist / std::sin(
lineAngle * M_PI / 180 );
2976 lineAngle = 180 * std::atan2(
static_cast< double >( height ),
static_cast< double >( width ) ) / M_PI;
2982 height = std::abs( height );
2983 width = std::abs( width );
2985 outputPixelDist = std::abs( height * std::cos(
lineAngle * M_PI / 180 ) );
2989 int offsetHeight =
static_cast< int >( std::round( outputPixelOffset / std::cos(
lineAngle * M_PI / 180 ) ) );
2990 outputPixelOffset = offsetHeight * std::cos(
lineAngle * M_PI / 180 );
2999 int bufferMulti =
static_cast< int >( std::max( std::ceil( outputPixelBleed / width ), std::ceil( outputPixelBleed / width ) ) );
3003 bufferMulti = std::max( bufferMulti, 1 );
3005 int xBuffer = width * bufferMulti;
3006 int yBuffer = height * bufferMulti;
3007 int innerWidth = width;
3008 int innerHeight = height;
3009 width += 2 * xBuffer;
3010 height += 2 * yBuffer;
3013 if ( width > 2000 || height > 2000 || width == 0 || height == 0 )
3018 QImage patternImage( width, height, QImage::Format_ARGB32 );
3019 patternImage.fill( 0 );
3021 QPointF p1, p2, p3, p4, p5, p6;
3024 p1 = QPointF( 0, yBuffer );
3025 p2 = QPointF( width, yBuffer );
3026 p3 = QPointF( 0, yBuffer + innerHeight );
3027 p4 = QPointF( width, yBuffer + innerHeight );
3031 p1 = QPointF( xBuffer, height );
3032 p2 = QPointF( xBuffer, 0 );
3033 p3 = QPointF( xBuffer + innerWidth, height );
3034 p4 = QPointF( xBuffer + innerWidth, 0 );
3038 dx = outputPixelDist * std::cos( ( 90 -
lineAngle ) * M_PI / 180.0 );
3039 dy = outputPixelDist * std::sin( ( 90 -
lineAngle ) * M_PI / 180.0 );
3040 p1 = QPointF( 0, height );
3041 p2 = QPointF( width, 0 );
3042 p3 = QPointF( -dx, height - dy );
3043 p4 = QPointF( width - dx, -dy );
3044 p5 = QPointF( dx, height + dy );
3045 p6 = QPointF( width + dx, dy );
3049 dx = outputPixelDist * std::cos( ( 90 -
lineAngle ) * M_PI / 180.0 );
3050 dy = outputPixelDist * std::sin( ( 90 -
lineAngle ) * M_PI / 180.0 );
3051 p1 = QPointF( width, 0 );
3052 p2 = QPointF( 0, height );
3053 p3 = QPointF( width - dx, -dy );
3054 p4 = QPointF( -dx, height - dy );
3055 p5 = QPointF( width + dx, dy );
3056 p6 = QPointF( dx, height + dy );
3060 dy = outputPixelDist * std::cos( ( 180 -
lineAngle ) * M_PI / 180 );
3061 dx = outputPixelDist * std::sin( ( 180 -
lineAngle ) * M_PI / 180 );
3062 p1 = QPointF( 0, 0 );
3063 p2 = QPointF( width, height );
3064 p5 = QPointF( dx, -dy );
3065 p6 = QPointF( width + dx, height - dy );
3066 p3 = QPointF( -dx, dy );
3067 p4 = QPointF( width - dx, height + dy );
3071 dy = outputPixelDist * std::cos( ( 180 -
lineAngle ) * M_PI / 180 );
3072 dx = outputPixelDist * std::sin( ( 180 -
lineAngle ) * M_PI / 180 );
3073 p1 = QPointF( width, height );
3074 p2 = QPointF( 0, 0 );
3075 p5 = QPointF( width + dx, height - dy );
3076 p6 = QPointF( dx, -dy );
3077 p3 = QPointF( width - dx, height + dy );
3078 p4 = QPointF( -dx, dy );
3085 p3 = QPointF( tempPt.x(), tempPt.y() );
3087 p4 = QPointF( tempPt.x(), tempPt.y() );
3089 p5 = QPointF( tempPt.x(), tempPt.y() );
3091 p6 = QPointF( tempPt.x(), tempPt.y() );
3095 p1 = QPointF( tempPt.x(), tempPt.y() );
3097 p2 = QPointF( tempPt.x(), tempPt.y() );
3100 QPainter p( &patternImage );
3104 p.setRenderHint( QPainter::Antialiasing,
false );
3105 QPen pen( QColor( Qt::black ) );
3106 pen.setWidthF( 0.1 );
3107 pen.setCapStyle( Qt::FlatCap );
3112 QPolygon polygon = QPolygon() << QPoint( 0, 0 ) << QPoint( width - 1, 0 ) << QPoint( width - 1, height - 1 ) << QPoint( 0, height - 1 ) << QPoint( 0, 0 );
3113 p.drawPolygon( polygon );
3115 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 );
3116 p.drawPolygon( polygon );
3122 p.setRenderHint( QPainter::Antialiasing,
true );
3136 fillLineSymbol->startRender( lineRenderContext, context.
fields() );
3138 QVector<QPolygonF> polygons;
3139 polygons.append( QPolygonF() << p1 << p2 );
3140 polygons.append( QPolygonF() << p3 << p4 );
3143 polygons.append( QPolygonF() << p5 << p6 );
3147 for (
const QPolygonF &polygon : std::as_const( polygons ) )
3149 fillLineSymbol->renderPolyline( polygon, context.
feature(), lineRenderContext, -1, useSelectedColor );
3152 fillLineSymbol->stopRender( lineRenderContext );
3156 patternImage = patternImage.copy( xBuffer, yBuffer, patternImage.width() - 2 * xBuffer, patternImage.height() - 2 * yBuffer );
3161 QImage transparentImage = patternImage.copy();
3163 brush.setTextureImage( transparentImage );
3167 brush.setTextureImage( patternImage );
3170 QTransform brushTransform;
3171 brush.setTransform( brushTransform );
3181 || ( mFillLineSymbol && mFillLineSymbol->hasDataDefinedProperties() )
3185 if ( !mRenderUsingLines )
3189 mRenderUsingLines = !applyPattern( context,
mBrush, mLineAngle, mDistance );
3192 if ( mRenderUsingLines && mFillLineSymbol )
3196 mFillLineSymbolRenderStarted =
true;
3202 if ( mFillLineSymbolRenderStarted )
3205 mFillLineSymbolRenderStarted =
false;
3212 if ( !useSelectedColor && !mRenderUsingLines )
3219 if ( !mFillLineSymbolRenderStarted && mFillLineSymbol )
3223 mFillLineSymbolRenderStarted =
true;
3253 outputPixelOffset = std::fmod( outputPixelOffset, outputPixelDistance );
3254 if ( outputPixelOffset > outputPixelDistance / 2.0 )
3255 outputPixelOffset -= outputPixelDistance;
3257 p->setPen( QPen( Qt::NoPen ) );
3279 std::unique_ptr< QgsPolygon > shapePolygon;
3280 std::unique_ptr< QgsGeometryEngine > shapeEngine;
3288 shapePolygon = std::make_unique< QgsPolygon >();
3290 shapePolygon->setExteriorRing( fromPolygon.release() );
3293 for (
const QPolygonF &ring : *rings )
3296 shapePolygon->addInteriorRing( fromRing.release() );
3300 shapeEngine->prepareGeometry();
3307 path.addPolygon( points );
3310 for (
const QPolygonF &ring : *rings )
3312 path.addPolygon( ring );
3315 p->setClipPath( path, Qt::IntersectClip );
3321 const QRectF boundingRect = points.boundingRect();
3323 QTransform invertedRotateTransform;
3329 QTransform transform;
3330 if ( applyBrushTransform )
3333 transform.translate( -boundingRect.center().x(),
3334 -boundingRect.center().y() );
3336 transform.translate( boundingRect.center().x(),
3337 boundingRect.center().y() );
3345 const QRectF transformedBounds = transform.map( points ).boundingRect();
3349 left = transformedBounds.left() - buffer * 2;
3350 top = transformedBounds.top() - buffer * 2;
3351 right = transformedBounds.right() + buffer * 2;
3352 bottom = transformedBounds.bottom() + buffer * 2;
3353 invertedRotateTransform = transform.inverted();
3355 if ( !applyBrushTransform )
3357 top -= transformedBounds.top() - ( outputPixelDistance * std::floor( transformedBounds.top() / outputPixelDistance ) );
3362 const bool needsExpressionContext = mFillLineSymbol->hasDataDefinedProperties();
3367 int currentLine = 0;
3368 for (
double currentY = top; currentY <= bottom; currentY += outputPixelDistance )
3373 if ( needsExpressionContext )
3377 double y1 = currentY;
3379 double y2 = currentY;
3380 invertedRotateTransform.map( left, currentY - outputPixelOffset, &x1, &y1 );
3381 invertedRotateTransform.map( right, currentY - outputPixelOffset, &x2, &y2 );
3386 std::unique_ptr< QgsAbstractGeometry > intersection( shapeEngine->intersection( &ls ) );
3387 for (
auto it = intersection->const_parts_begin(); it != intersection->const_parts_end(); ++it )
3389 if (
const QgsLineString *ls = qgsgeometry_cast< const QgsLineString * >( *it ) )
3397 mFillLineSymbol->renderPolyline( QPolygonF() << QPointF( x1, y1 ) << QPointF( x2, y2 ), context.
feature(), context.
renderContext(), -1, useSelectedColor );
3409 map.insert( QStringLiteral(
"angle" ), QString::number( mLineAngle ) );
3410 map.insert( QStringLiteral(
"distance" ), QString::number( mDistance ) );
3411 map.insert( QStringLiteral(
"line_width" ), QString::number( mLineWidth ) );
3413 map.insert( QStringLiteral(
"offset" ), QString::number( mOffset ) );
3429 if ( mFillLineSymbol )
3440 QDomElement symbolizerElem = doc.createElement( QStringLiteral(
"se:PolygonSymbolizer" ) );
3441 if ( !props.value( QStringLiteral(
"uom" ), QString() ).toString().isEmpty() )
3442 symbolizerElem.setAttribute( QStringLiteral(
"uom" ), props.value( QStringLiteral(
"uom" ), QString() ).toString() );
3443 element.appendChild( symbolizerElem );
3448 QDomElement fillElem = doc.createElement( QStringLiteral(
"se:Fill" ) );
3449 symbolizerElem.appendChild( fillElem );
3451 QDomElement graphicFillElem = doc.createElement( QStringLiteral(
"se:GraphicFill" ) );
3452 fillElem.appendChild( graphicFillElem );
3454 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
3455 graphicFillElem.appendChild( graphicElem );
3460 bool exportOk {
false };
3464 if ( ! image.isNull() )
3466 const QFileInfo info { context.exportFilePath() };
3467 QString pngPath { info.completeSuffix().isEmpty() ? context.exportFilePath() : context.exportFilePath().chopped( info.completeSuffix().length() ).append( QStringLiteral(
"png" ) ) };
3469 image.save( pngPath );
3478 QColor lineColor = mFillLineSymbol ? mFillLineSymbol->color() : QColor();
3479 double lineWidth = mFillLineSymbol ? mFillLineSymbol->width() : 0.0;
3487 double angle = props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toDouble( &ok );
3490 angleFunc = QStringLiteral(
"%1 + %2" ).arg( props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toString() ).arg( mLineAngle );
3494 angleFunc = QString::number(
angle + mLineAngle );
3499 QPointF lineOffset( std::sin( mLineAngle ) * mOffset, std::cos( mLineAngle ) * mOffset );
3507 QString featureStyle;
3508 featureStyle.append(
"Brush(" );
3509 featureStyle.append( QStringLiteral(
"fc:%1" ).arg(
mColor.name() ) );
3510 featureStyle.append( QStringLiteral(
",bc:%1" ).arg( QLatin1String(
"#00000000" ) ) );
3511 featureStyle.append(
",id:\"ogr-brush-2\"" );
3512 featureStyle.append( QStringLiteral(
",a:%1" ).arg( mLineAngle ) );
3513 featureStyle.append( QStringLiteral(
",s:%1" ).arg( mLineWidth * widthScaleFactor ) );
3514 featureStyle.append(
",dx:0mm" );
3515 featureStyle.append( QStringLiteral(
",dy:%1mm" ).arg( mDistance * widthScaleFactor ) );
3516 featureStyle.append(
')' );
3517 return featureStyle;
3523 && ( !mFillLineSymbol || !mFillLineSymbol->hasDataDefinedProperties() ) )
3548 Qt::PenStyle lineStyle;
3550 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
3551 if ( fillElem.isNull() )
3554 QDomElement graphicFillElem = fillElem.firstChildElement( QStringLiteral(
"GraphicFill" ) );
3555 if ( graphicFillElem.isNull() )
3558 QDomElement graphicElem = graphicFillElem.firstChildElement( QStringLiteral(
"Graphic" ) );
3559 if ( graphicElem.isNull() )
3565 if ( name != QLatin1String(
"horline" ) )
3573 double d = angleFunc.toDouble( &ok );
3582 offset = std::sqrt( std::pow( vectOffset.x(), 2 ) + std::pow( vectOffset.y(), 2 ) );
3585 double scaleFactor = 1.0;
3586 const QString uom = element.attribute( QStringLiteral(
"uom" ) );
3588 size = size * scaleFactor;
3591 auto sl = std::make_unique< QgsLinePatternFillSymbolLayer >();
3592 sl->setOutputUnit( sldUnitSize );
3593 sl->setColor( lineColor );
3595 sl->setLineAngle(
angle );
3597 sl->setDistance( size );
3600 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
3601 if ( !strokeElem.isNull() )
3607 layers.append( l.release() );
3612 return sl.release();
3712 auto layer = std::make_unique< QgsPointPatternFillSymbolLayer >();
3713 if (
properties.contains( QStringLiteral(
"distance_x" ) ) )
3715 layer->setDistanceX(
properties[QStringLiteral(
"distance_x" )].toDouble() );
3717 if (
properties.contains( QStringLiteral(
"distance_y" ) ) )
3719 layer->setDistanceY(
properties[QStringLiteral(
"distance_y" )].toDouble() );
3721 if (
properties.contains( QStringLiteral(
"displacement_x" ) ) )
3723 layer->setDisplacementX(
properties[QStringLiteral(
"displacement_x" )].toDouble() );
3725 if (
properties.contains( QStringLiteral(
"displacement_y" ) ) )
3727 layer->setDisplacementY(
properties[QStringLiteral(
"displacement_y" )].toDouble() );
3729 if (
properties.contains( QStringLiteral(
"offset_x" ) ) )
3731 layer->setOffsetX(
properties[QStringLiteral(
"offset_x" )].toDouble() );
3733 if (
properties.contains( QStringLiteral(
"offset_y" ) ) )
3735 layer->setOffsetY(
properties[QStringLiteral(
"offset_y" )].toDouble() );
3738 if (
properties.contains( QStringLiteral(
"distance_x_unit" ) ) )
3742 if (
properties.contains( QStringLiteral(
"distance_x_map_unit_scale" ) ) )
3746 if (
properties.contains( QStringLiteral(
"distance_y_unit" ) ) )
3750 if (
properties.contains( QStringLiteral(
"distance_y_map_unit_scale" ) ) )
3754 if (
properties.contains( QStringLiteral(
"displacement_x_unit" ) ) )
3758 if (
properties.contains( QStringLiteral(
"displacement_x_map_unit_scale" ) ) )
3762 if (
properties.contains( QStringLiteral(
"displacement_y_unit" ) ) )
3766 if (
properties.contains( QStringLiteral(
"displacement_y_map_unit_scale" ) ) )
3770 if (
properties.contains( QStringLiteral(
"offset_x_unit" ) ) )
3774 if (
properties.contains( QStringLiteral(
"offset_x_map_unit_scale" ) ) )
3778 if (
properties.contains( QStringLiteral(
"offset_y_unit" ) ) )
3782 if (
properties.contains( QStringLiteral(
"offset_y_map_unit_scale" ) ) )
3787 if (
properties.contains( QStringLiteral(
"random_deviation_x" ) ) )
3789 layer->setMaximumRandomDeviationX(
properties[QStringLiteral(
"random_deviation_x" )].toDouble() );
3791 if (
properties.contains( QStringLiteral(
"random_deviation_y" ) ) )
3793 layer->setMaximumRandomDeviationY(
properties[QStringLiteral(
"random_deviation_y" )].toDouble() );
3795 if (
properties.contains( QStringLiteral(
"random_deviation_x_unit" ) ) )
3799 if (
properties.contains( QStringLiteral(
"random_deviation_x_map_unit_scale" ) ) )
3803 if (
properties.contains( QStringLiteral(
"random_deviation_y_unit" ) ) )
3807 if (
properties.contains( QStringLiteral(
"random_deviation_y_map_unit_scale" ) ) )
3811 unsigned long seed = 0;
3812 if (
properties.contains( QStringLiteral(
"seed" ) ) )
3818 std::random_device rd;
3819 std::mt19937 mt(
seed == 0 ? rd() :
seed );
3820 std::uniform_int_distribution<> uniformDist( 1, 999999999 );
3821 seed = uniformDist( mt );
3823 layer->setSeed(
seed );
3825 if (
properties.contains( QStringLiteral(
"outline_width_unit" ) ) )
3829 if (
properties.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
3833 if (
properties.contains( QStringLiteral(
"clip_mode" ) ) )
3837 if (
properties.contains( QStringLiteral(
"coordinate_reference" ) ) )
3842 if (
properties.contains( QStringLiteral(
"angle" ) ) )
3844 layer->setAngle(
properties[QStringLiteral(
"angle" )].toDouble() );
3849 return layer.release();
3854 return QStringLiteral(
"PointPatternFill" );
3857bool QgsPointPatternFillSymbolLayer::applyPattern(
const QgsSymbolRenderContext &context, QBrush &brush,
double distanceX,
double distanceY,
3858 double displacementX,
double displacementY,
double offsetX,
double offsetY )
3865 double widthOffset = std::fmod(
3868 double heightOffset = std::fmod(
3872 if ( width > 2000 || height > 2000 )
3874 brush.setTextureImage( QImage() );
3878 QImage patternImage( width, height, QImage::Format_ARGB32 );
3879 patternImage.fill( 0 );
3880 if ( patternImage.isNull() )
3882 brush.setTextureImage( QImage() );
3887 QPainter p( &patternImage );
3906 for (
double currentX = -width; currentX <= width * 2.0; currentX += width )
3908 for (
double currentY = -height; currentY <= height * 2.0; currentY += height )
3910 mMarkerSymbol->renderPoint( QPointF( currentX + widthOffset, currentY + heightOffset ), context.
feature(), pointRenderContext );
3921 for (
double currentX = -width; currentX <= width * 2.0; currentX += width )
3923 for (
double currentY = -height / 2.0; currentY <= height * 2.0; currentY += height )
3925 mMarkerSymbol->renderPoint( QPointF( currentX + widthOffset + displacementPixelX, currentY + heightOffset ), context.
feature(), pointRenderContext );
3929 for (
double currentX = -width / 2.0; currentX <= width * 2.0; currentX += width )
3931 for (
double currentY = -height; currentY <= height * 2.0; currentY += height / 2.0 )
3933 mMarkerSymbol->renderPoint( QPointF( currentX + widthOffset + ( std::fmod( currentY, height ) != 0 ? displacementPixelX : 0 ), currentY + heightOffset - displacementPixelY ), context.feature(), pointRenderContext );
3942 QImage transparentImage = patternImage.copy();
3944 brush.setTextureImage( transparentImage );
3948 brush.setTextureImage( patternImage );
3950 QTransform brushTransform;
3951 brush.setTransform( brushTransform );
3971 if ( !mRenderUsingMarkers )
4016 if ( !useSelectedColor && !mRenderUsingMarkers )
4066 const double widthOffset = std::fmod(
4078 const double heightOffset = std::fmod(
4104 p->setPen( QPen( Qt::NoPen ) );
4126 std::unique_ptr< QgsPolygon > shapePolygon;
4127 std::unique_ptr< QgsGeometryEngine > shapeEngine;
4134 shapePolygon = std::make_unique< QgsPolygon >();
4136 shapePolygon->setExteriorRing( fromPolygon.release() );
4139 for (
const QPolygonF &ring : *rings )
4142 shapePolygon->addInteriorRing( fromRing.release() );
4146 shapeEngine->prepareGeometry();
4153 path.addPolygon( points );
4156 for (
const QPolygonF &ring : *rings )
4158 path.addPolygon( ring );
4161 p->setClipPath( path, Qt::IntersectClip );
4167 const QRectF boundingRect = points.boundingRect();
4169 QTransform invertedRotateTransform;
4177 QTransform transform;
4178 if ( applyBrushTransform )
4181 transform.translate( -boundingRect.center().x(),
4182 -boundingRect.center().y() );
4183 transform.rotate( -
angle );
4184 transform.translate( boundingRect.center().x(),
4185 boundingRect.center().y() );
4190 transform.rotate( -
angle );
4193 const QRectF transformedBounds = transform.map( points ).boundingRect();
4194 left = transformedBounds.left() - 2 * width;
4195 top = transformedBounds.top() - 2 * height;
4196 right = transformedBounds.right() + 2 * width;
4197 bottom = transformedBounds.bottom() + 2 * height;
4198 invertedRotateTransform = transform.inverted();
4200 if ( !applyBrushTransform )
4202 left -= transformedBounds.left() - ( width * std::floor( transformedBounds.left() / width ) );
4203 top -= transformedBounds.top() - ( height * std::floor( transformedBounds.top() / height ) );
4208 left = boundingRect.left() - 2 * width;
4209 top = boundingRect.top() - 2 * height;
4210 right = boundingRect.right() + 2 * width;
4211 bottom = boundingRect.bottom() + 2 * height;
4213 if ( !applyBrushTransform )
4215 left -= boundingRect.left() - ( width * std::floor( boundingRect.left() / width ) );
4216 top -= boundingRect.top() - ( height * std::floor( boundingRect.top() / height ) );
4245 std::random_device rd;
4246 std::mt19937 mt(
seed == 0 ? rd() :
seed );
4247 std::uniform_real_distribution<> uniformDist( 0, 1 );
4253 const bool needsExpressionContext =
mMarkerSymbol->hasDataDefinedProperties();
4261 bool alternateColumn =
false;
4262 int currentCol = -3;
4263 for (
double currentX = left; currentX <= right; currentX += width, alternateColumn = !alternateColumn )
4268 if ( needsExpressionContext )
4271 bool alternateRow =
false;
4272 const double columnX = currentX + widthOffset;
4273 int currentRow = -3;
4274 for (
double currentY = top; currentY <= bottom; currentY += height, alternateRow = !alternateRow )
4279 double y = currentY + heightOffset;
4282 x += displacementPixelX;
4284 if ( !alternateColumn )
4285 y -= displacementPixelY;
4291 invertedRotateTransform.map( xx, yy, &x, &y );
4294 if ( useRandomShift )
4296 x += ( 2 * uniformDist( mt ) - 1 ) * maxRandomDeviationPixelX;
4297 y += ( 2 * uniformDist( mt ) - 1 ) * maxRandomDeviationPixelY;
4300 if ( needsExpressionContext )
4308 bool renderPoint =
true;
4316 renderPoint = shapeEngine->intersects( &p );
4328 renderPoint = shapeEngine->intersects( markerBounds.
constGet() );
4354 map.insert( QStringLiteral(
"distance_x" ), QString::number(
mDistanceX ) );
4355 map.insert( QStringLiteral(
"distance_y" ), QString::number(
mDistanceY ) );
4356 map.insert( QStringLiteral(
"displacement_x" ), QString::number(
mDisplacementX ) );
4357 map.insert( QStringLiteral(
"displacement_y" ), QString::number(
mDisplacementY ) );
4358 map.insert( QStringLiteral(
"offset_x" ), QString::number(
mOffsetX ) );
4359 map.insert( QStringLiteral(
"offset_y" ), QString::number(
mOffsetY ) );
4375 map.insert( QStringLiteral(
"random_deviation_x" ), QString::number(
mRandomDeviationX ) );
4376 map.insert( QStringLiteral(
"random_deviation_y" ), QString::number(
mRandomDeviationY ) );
4381 map.insert( QStringLiteral(
"seed" ), QString::number(
mSeed ) );
4382 map.insert( QStringLiteral(
"angle" ),
mAngle );
4401 for (
int symbolLayerIdx = 0; symbolLayerIdx <
mMarkerSymbol->symbolLayerCount(); symbolLayerIdx++ )
4403 QDomElement symbolizerElem = doc.createElement( QStringLiteral(
"se:PolygonSymbolizer" ) );
4404 if ( !props.value( QStringLiteral(
"uom" ), QString() ).toString().isEmpty() )
4405 symbolizerElem.setAttribute( QStringLiteral(
"uom" ), props.value( QStringLiteral(
"uom" ), QString() ).toString() );
4406 element.appendChild( symbolizerElem );
4411 QDomElement fillElem = doc.createElement( QStringLiteral(
"se:Fill" ) );
4412 symbolizerElem.appendChild( fillElem );
4414 QDomElement graphicFillElem = doc.createElement( QStringLiteral(
"se:GraphicFill" ) );
4415 fillElem.appendChild( graphicFillElem );
4422 bool exportOk {
false };
4426 if ( ! image.isNull() )
4428 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
4429 graphicFillElem.appendChild( graphicElem );
4430 const QFileInfo info { context.exportFilePath() };
4431 QString pngPath { info.completeSuffix().isEmpty() ? context.exportFilePath() : context.exportFilePath().chopped( info.completeSuffix().length() ).append( QStringLiteral(
"png" ) ) };
4433 image.save( pngPath );
4452 symbolizerElem.appendChild( graphicMarginElem );
4456 markerLayer->writeSldMarker( doc, graphicFillElem, props );
4460 QString errorMsg = QStringLiteral(
"QgsMarkerSymbolLayer expected, %1 found. Skip it." ).arg( layer->
layerType() );
4461 graphicFillElem.appendChild( doc.createComment( errorMsg ) );
4465 QString errorMsg = QStringLiteral(
"Missing point pattern symbol layer. Skip it." );
4466 graphicFillElem.appendChild( doc.createComment( errorMsg ) );
4475 double angleRads { qDegreesToRadians(
mAngle ) };
4484 if ( displacementXPx != 0 )
4489 if ( displacementYPx != 0 )
4496 QPixmap pixmap( size );
4497 pixmap.fill( Qt::transparent );
4499 painter.begin( &pixmap );
4500 painter.setRenderHint( QPainter::Antialiasing );
4508 std::unique_ptr< QgsPointPatternFillSymbolLayer > layerClone(
clone() );
4510 layerClone->setAngle( qRadiansToDegrees( angleRads ) );
4513 layerClone->setMaximumRandomDeviationX( 0 );
4514 layerClone->setMaximumRandomDeviationY( 0 );
4516 layerClone->drawPreviewIcon( symbolContext, pixmap.size() );
4518 return pixmap.toImage();
4526 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
4527 if ( fillElem.isNull() )
4530 QDomElement graphicFillElem = fillElem.firstChildElement( QStringLiteral(
"GraphicFill" ) );
4531 if ( graphicFillElem.isNull() )
4534 QDomElement graphicElem = graphicFillElem.firstChildElement( QStringLiteral(
"Graphic" ) );
4535 if ( graphicElem.isNull() )
4539 if ( !simpleMarkerSl )
4543 layers.append( simpleMarkerSl.release() );
4545 auto marker = std::make_unique< QgsMarkerSymbol >( layers );
4548 const double markerSize { marker->size() };
4550 auto pointPatternFillSl = std::make_unique< QgsPointPatternFillSymbolLayer >();
4551 pointPatternFillSl->setSubSymbol( marker.release() );
4556 auto distanceParser = [ & ](
const QStringList & values )
4558 switch ( values.count( ) )
4563 const double v { values.at( 0 ).toDouble( &ok ) };
4566 pointPatternFillSl->setDistanceX( v * 2 + markerSize );
4567 pointPatternFillSl->setDistanceY( v * 2 + markerSize );
4574 const double vX { values.at( 1 ).toDouble( &ok ) };
4577 pointPatternFillSl->setDistanceX( vX * 2 + markerSize );
4579 const double vY { values.at( 0 ).toDouble( &ok ) };
4582 pointPatternFillSl->setDistanceY( vY * 2 + markerSize );
4589 const double vX { values.at( 1 ).toDouble( &ok ) };
4592 pointPatternFillSl->setDistanceX( vX * 2 + markerSize );
4594 const double vYt { values.at( 0 ).toDouble( &ok ) };
4597 const double vYb { values.at( 2 ).toDouble( &ok ) };
4600 pointPatternFillSl->setDistanceY( ( vYt + vYb ) + markerSize );
4608 const double vYt { values.at( 0 ).toDouble( &ok ) };
4611 const double vYb { values.at( 2 ).toDouble( &ok ) };
4614 pointPatternFillSl->setDistanceY( ( vYt + vYb ) + markerSize );
4617 const double vXr { values.at( 1 ).toDouble( &ok ) };
4620 const double vXl { values.at( 3 ).toDouble( &ok ) };
4623 pointPatternFillSl->setDistanceX( ( vXr + vXl ) + markerSize );
4634 bool distanceFromVendorOption {
false };
4636 for ( QgsStringMap::iterator it = vendorOptions.begin(); it != vendorOptions.end(); ++it )
4639 if ( it.key() == QLatin1String(
"distance" ) )
4641 distanceParser( it.value().split(
',' ) );
4642 distanceFromVendorOption =
true;
4645 else if ( it.key() == QLatin1String(
"graphic-margin" ) )
4647 distanceParser( it.value().split(
' ' ) );
4648 distanceFromVendorOption =
true;
4653 if ( ! distanceFromVendorOption && ! graphicFillElem.elementsByTagName( QStringLiteral(
"Size" ) ).isEmpty() )
4655 const QDomElement sizeElement { graphicFillElem.elementsByTagName( QStringLiteral(
"Size" ) ).at( 0 ).toElement() };
4657 const double size { sizeElement.text().toDouble( &ok ) };
4660 pointPatternFillSl->setDistanceX( size );
4661 pointPatternFillSl->setDistanceY( size );
4665 return pointPatternFillSl.release();
4747 attributes.unite(
mMarkerSymbol->usedAttributes( context ) );
4785 auto sl = std::make_unique< QgsCentroidFillSymbolLayer >();
4787 if (
properties.contains( QStringLiteral(
"point_on_surface" ) ) )
4788 sl->setPointOnSurface(
properties[QStringLiteral(
"point_on_surface" )].toInt() != 0 );
4789 if (
properties.contains( QStringLiteral(
"point_on_all_parts" ) ) )
4790 sl->setPointOnAllParts(
properties[QStringLiteral(
"point_on_all_parts" )].toInt() != 0 );
4791 if (
properties.contains( QStringLiteral(
"clip_points" ) ) )
4792 sl->setClipPoints(
properties[QStringLiteral(
"clip_points" )].toInt() != 0 );
4793 if (
properties.contains( QStringLiteral(
"clip_on_current_part_only" ) ) )
4794 sl->setClipOnCurrentPartOnly(
properties[QStringLiteral(
"clip_on_current_part_only" )].toInt() != 0 );
4796 sl->restoreOldDataDefinedProperties(
properties );
4798 return sl.release();
4803 return QStringLiteral(
"CentroidFill" );
4831 part.exterior = points;
4833 part.rings = *rings;
4841 mCurrentParts << part;
4846 const double prevOpacity =
mMarker->opacity();
4850 mMarker->setOpacity( prevOpacity );
4859 mCurrentParts.clear();
4866 const double prevOpacity =
mMarker->opacity();
4872 mMarker->setOpacity( prevOpacity );
4877void QgsCentroidFillSymbolLayer::render(
QgsRenderContext &context,
const QVector<QgsCentroidFillSymbolLayer::Part> &parts,
const QgsFeature &feature,
bool selected )
4886 QVector< QgsGeometry > geometryParts;
4887 geometryParts.reserve( parts.size() );
4888 QPainterPath globalPath;
4891 int maxAreaPartIdx = 0;
4893 for (
int i = 0; i < parts.size(); i++ )
4895 const Part part = parts[i];
4898 if ( !geom.
isNull() && !part.rings.empty() )
4900 QgsPolygon *poly = qgsgeometry_cast< QgsPolygon * >( geom.
get() );
4904 int area = poly->
area();
4906 if ( area > maxArea )
4916 globalPath.addPolygon( part.exterior );
4917 for (
const QPolygonF &ring : part.rings )
4919 globalPath.addPolygon( ring );
4924 for (
int i = 0; i < parts.size(); i++ )
4929 const Part part = parts[i];
4937 path.addPolygon( part.exterior );
4938 for (
const QPolygonF &ring : part.rings )
4940 path.addPolygon( ring );
4949 context.
painter()->setClipPath( path );
4956 mMarker->renderPoint( centroid, feature.
isValid() ? &feature : nullptr, context, -1, selected );
4969 map[QStringLiteral(
"point_on_surface" )] = QString::number(
mPointOnSurface );
4970 map[QStringLiteral(
"point_on_all_parts" )] = QString::number(
mPointOnAllParts );
4971 map[QStringLiteral(
"clip_points" )] = QString::number(
mClipPoints );
4978 auto x = std::make_unique< QgsCentroidFillSymbolLayer >();
4981 x->setSubSymbol(
mMarker->clone() );
4996 mMarker->toSld( doc, element, props );
5006 layers.append( l.release() );
5007 auto marker = std::make_unique<QgsMarkerSymbol>( layers );
5009 auto sl = std::make_unique< QgsCentroidFillSymbolLayer >();
5010 sl->setSubSymbol( marker.release() );
5011 sl->setPointOnAllParts(
false );
5012 return sl.release();
5039 attributes.unite(
mMarker->usedAttributes( context ) );
5062 mMarker->setOutputUnit( unit );
5079 return mMarker->usesMapUnits();
5088 mMarker->setMapUnitScale( scale );
5096 return mMarker->mapUnitScale();
5106 , mImageFilePath( imageFilePath )
5123 if (
properties.contains( QStringLiteral(
"imageFile" ) ) )
5125 imagePath =
properties[QStringLiteral(
"imageFile" )].toString();
5127 if (
properties.contains( QStringLiteral(
"coordinate_mode" ) ) )
5131 if (
properties.contains( QStringLiteral(
"alpha" ) ) )
5133 alpha =
properties[QStringLiteral(
"alpha" )].toDouble();
5135 if (
properties.contains( QStringLiteral(
"offset" ) ) )
5139 if (
properties.contains( QStringLiteral(
"angle" ) ) )
5143 if (
properties.contains( QStringLiteral(
"width" ) ) )
5147 auto symbolLayer = std::make_unique< QgsRasterFillSymbolLayer >( imagePath );
5148 symbolLayer->setCoordinateMode( mode );
5149 symbolLayer->setOpacity( alpha );
5150 symbolLayer->setOffset(
offset );
5151 symbolLayer->setAngle(
angle );
5152 symbolLayer->setWidth(
width );
5153 if (
properties.contains( QStringLiteral(
"offset_unit" ) ) )
5157 if (
properties.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
5161 if (
properties.contains( QStringLiteral(
"width_unit" ) ) )
5165 if (
properties.contains( QStringLiteral(
"width_map_unit_scale" ) ) )
5170 if (
properties.contains( QStringLiteral(
"height" ) ) )
5172 symbolLayer->setHeight(
properties[QStringLiteral(
"height" )].toDouble() );
5175 symbolLayer->restoreOldDataDefinedProperties(
properties );
5177 return symbolLayer.release();
5182 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
5183 if ( fillElem.isNull() )
5186 QDomElement graphicFillElem = fillElem.firstChildElement( QStringLiteral(
"GraphicFill" ) );
5187 if ( graphicFillElem.isNull() )
5190 QDomElement graphicElem = graphicFillElem.firstChildElement( QStringLiteral(
"Graphic" ) );
5191 if ( graphicElem.isNull() )
5194 QString path, mimeType;
5202 if ( ! QFile::exists( path ) )
5207 auto sl = std::make_unique< QgsRasterFillSymbolLayer>( path );
5209 return sl.release();
5214 QVariantMap::iterator it =
properties.find( QStringLiteral(
"imageFile" ) );
5218 it.value() = pathResolver.
writePath( it.value().toString() );
5220 it.value() = pathResolver.
readPath( it.value().toString() );
5232 return QStringLiteral(
"RasterFill" );
5248 QPointF
offset = mOffset;
5266 QRectF boundingRect = points.boundingRect();
5267 mBrush.setTransform(
mBrush.transform().translate( boundingRect.left() -
mBrush.transform().dx(),
5268 boundingRect.top() -
mBrush.transform().dy() ) );
5280 applyPattern(
mBrush, mImageFilePath, mWidth, mHeight, mOpacity * context.
opacity(), context );
5291 map[QStringLiteral(
"imageFile" )] = mImageFilePath;
5292 map[QStringLiteral(
"coordinate_mode" )] = QString::number(
static_cast< int >( mCoordinateMode ) );
5293 map[QStringLiteral(
"alpha" )] = QString::number( mOpacity );
5297 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
5299 map[QStringLiteral(
"width" )] = QString::number( mWidth );
5300 map[QStringLiteral(
"height" )] = QString::number( mHeight );
5309 auto sl = std::make_unique< QgsRasterFillSymbolLayer >( mImageFilePath );
5310 sl->setCoordinateMode( mCoordinateMode );
5311 sl->setOpacity( mOpacity );
5312 sl->setOffset( mOffset );
5313 sl->setOffsetUnit( mOffsetUnit );
5314 sl->setOffsetMapUnitScale( mOffsetMapUnitScale );
5316 sl->setWidth( mWidth );
5317 sl->setHeight( mHeight );
5318 sl->setSizeUnit( mSizeUnit );
5319 sl->setSizeMapUnitScale( mSizeMapUnitScale );
5323 return sl.release();
5328 return context.
convertToPainterUnits( std::max( std::fabs( mOffset.x() ), std::fabs( mOffset.y() ) ), mOffsetUnit, mOffsetMapUnitScale );
5351 mImageFilePath = imagePath;
5356 mCoordinateMode = mode;
5375 if ( !hasWidthExpression && !hasHeightExpression && !hasAngleExpression && !hasOpacityExpression && !hasFileExpression )
5381 if ( hasAngleExpression )
5389 if ( !hasWidthExpression && !hasHeightExpression && !hasOpacityExpression && !hasFileExpression )
5394 double width = mWidth;
5395 if ( hasWidthExpression )
5401 if ( hasHeightExpression )
5407 if ( hasOpacityExpression )
5412 QString file = mImageFilePath;
5413 if ( hasFileExpression )
5426void QgsRasterFillSymbolLayer::applyPattern( QBrush &brush,
const QString &imageFilePath,
const double width,
const double height,
const double alpha,
const QgsSymbolRenderContext &context )
5428 double imageWidth = 0;
5429 double imageHeight = 0;
5444 if ( originalSize.isEmpty() )
5447 imageWidth = (
width * originalSize.width() ) / 100.0;
5450 if (
static_cast< int >( imageWidth ) < 1 || 10000.0 < imageWidth )
5463 if ( !originalSize.isValid() )
5466 if ( originalSize.isEmpty() )
5469 imageHeight = (
height * originalSize.height() ) / 100.0;
5472 if (
static_cast< int >( imageHeight ) < 1 || 10000.0 < imageHeight )
5477 if (
width == 0 && imageHeight > 0 )
5479 if ( !originalSize.isValid() )
5482 imageWidth = imageHeight * originalSize.width() / originalSize.height();
5484 else if (
height == 0 && imageWidth > 0 )
5486 if ( !originalSize.isValid() )
5489 imageHeight = imageWidth * originalSize.height() / originalSize.width();
5491 if ( imageWidth == 0 || imageHeight == 0 )
5493 if ( !originalSize.isValid() )
5496 imageWidth = originalSize.width();
5497 imageHeight = originalSize.height();
5505 brush.setTextureImage( img );
5514 : mCountMethod( method )
5515 , mPointCount( pointCount )
5516 , mDensityArea( densityArea )
5527 const int pointCount =
properties.value( QStringLiteral(
"point_count" ), QStringLiteral(
"10" ) ).toInt();
5528 const double densityArea =
properties.value( QStringLiteral(
"density_area" ), QStringLiteral(
"250.0" ) ).toDouble();
5530 unsigned long seed = 0;
5531 if (
properties.contains( QStringLiteral(
"seed" ) ) )
5537 std::random_device rd;
5538 std::mt19937 mt(
seed == 0 ? rd() :
seed );
5539 std::uniform_int_distribution<> uniformDist( 1, 999999999 );
5540 seed = uniformDist( mt );
5545 if (
properties.contains( QStringLiteral(
"density_area_unit" ) ) )
5547 if (
properties.contains( QStringLiteral(
"density_area_unit_scale" ) ) )
5550 if (
properties.contains( QStringLiteral(
"clip_points" ) ) )
5552 sl->setClipPoints(
properties[QStringLiteral(
"clip_points" )].toInt() );
5555 return sl.release();
5560 return QStringLiteral(
"RandomMarkerFill" );
5565 mMarker->setColor(
color );
5571 return mMarker ? mMarker->color() :
mColor;
5588 part.exterior = points;
5590 part.rings = *rings;
5592 if ( mRenderingFeature )
5596 mFeatureSymbolOpacity = context.
opacity();
5597 mCurrentParts << part;
5602 const double prevOpacity = mMarker->opacity();
5603 mMarker->setOpacity( mMarker->opacity() * context.
opacity() );
5606 mMarker->setOpacity( prevOpacity );
5610void QgsRandomMarkerFillSymbolLayer::render(
QgsRenderContext &context,
const QVector<QgsRandomMarkerFillSymbolLayer::Part> &parts,
const QgsFeature &feature,
bool selected )
5619 QVector< QgsGeometry > geometryParts;
5620 geometryParts.reserve( parts.size() );
5623 for (
const Part &part : parts )
5626 if ( !geom.
isNull() && !part.rings.empty() )
5628 QgsPolygon *poly = qgsgeometry_cast< QgsPolygon * >( geom.
get() );
5629 for (
const QPolygonF &ring : part.rings )
5637 geom = geom.
buffer( 0, 0 );
5639 geometryParts << geom;
5643 path.addPolygon( part.exterior );
5644 for (
const QPolygonF &ring : part.rings )
5646 path.addPolygon( ring );
5656 context.
painter()->setClipPath( path );
5660 int count = mPointCount;
5667 switch ( mCountMethod )
5679 count = std::max( 0.0, std::ceil( count * ( geom.
area() /
densityArea ) ) );
5686 unsigned long seed = mSeed;
5697 std::sort( randomPoints.begin(), randomPoints.end(), [](
const QgsPointXY & a,
const QgsPointXY & b )->bool
5699 return a.y() < b.y();
5705 const bool needsExpressionContext = mMarker->hasDataDefinedProperties();
5710 for (
const QgsPointXY &p : std::as_const( randomPoints ) )
5712 if ( needsExpressionContext )
5714 mMarker->renderPoint( QPointF( p.x(), p.y() ), feature.
isValid() ? &feature : nullptr, context, -1, selected );
5728 map.insert( QStringLiteral(
"count_method" ), QString::number(
static_cast< int >( mCountMethod ) ) );
5729 map.insert( QStringLiteral(
"point_count" ), QString::number( mPointCount ) );
5730 map.insert( QStringLiteral(
"density_area" ), QString::number( mDensityArea ) );
5733 map.insert( QStringLiteral(
"seed" ), QString::number( mSeed ) );
5734 map.insert( QStringLiteral(
"clip_points" ), QString::number( mClipPoints ) );
5740 auto res = std::make_unique< QgsRandomMarkerFillSymbolLayer >( mPointCount, mCountMethod, mDensityArea, mSeed );
5743 res->setDensityAreaUnit( mDensityAreaUnit );
5744 res->setDensityAreaUnitScale( mDensityAreaUnitScale );
5745 res->mClipPoints = mClipPoints;
5746 res->setSubSymbol( mMarker->clone() );
5749 return res.release();
5759 return mMarker.get();
5771 mColor = mMarker->color();
5780 attributes.unite( mMarker->usedAttributes( context ) );
5789 if ( mMarker && mMarker->hasDataDefinedProperties() )
5826 return mCountMethod;
5831 mCountMethod = method;
5836 return mDensityArea;
5841 mDensityArea = area;
5848 mRenderingFeature =
true;
5849 mCurrentParts.clear();
5854 mRenderingFeature =
false;
5856 const double prevOpacity = mMarker->opacity();
5857 mMarker->setOpacity( mMarker->opacity() * mFeatureSymbolOpacity );
5859 render( context, mCurrentParts, feature,
false );
5861 mFeatureSymbolOpacity = 1;
5862 mMarker->setOpacity( prevOpacity );
5870 mDensityAreaUnit = unit;
5873 mMarker->setOutputUnit( unit );
5881 return mMarker->outputUnit();
5890 return mMarker->usesMapUnits();
5899 mMarker->setMapUnitScale( scale );
5907 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.
@ IsSymbolLayerSubSymbol
Symbol is being rendered as a sub-symbol of a QgsSymbolLayer.
LineClipMode
Line clipping modes.
@ NoClipping
Lines are not clipped, will extend to shape's bounding box.
@ ClipPainterOnly
Applying clipping on the painter only (i.e. line endpoints will coincide with polygon bounding box,...
@ ClipToIntersection
Clip lines to intersection with polygon shape (slower) (i.e. line endpoints will coincide with polygo...
GradientColorSource
Gradient color sources.
@ ColorRamp
Gradient color ramp.
@ SimpleTwoColor
Simple two color gradient.
@ CanCalculateMaskGeometryPerFeature
If present, indicates that mask geometry can safely be calculated per feature for the symbol layer....
GradientSpread
Gradient spread options, which control how gradients are rendered outside of their start and end poin...
@ Reflect
Reflect gradient.
@ Pad
Pad out gradient using colors at endpoint of gradient.
@ Png
Export complex styles to separate PNG files for better compatibility with OGC servers.
PointCountMethod
Methods which define the number of points randomly filling a polygon.
@ Absolute
The point count is used as an absolute count of markers.
@ DensityBased
The point count is part of a marker density count.
QFlags< SymbolLayerFlag > SymbolLayerFlags
Symbol layer flags.
RenderUnit
Rendering size units.
@ Percentage
Percentage of another measurement (e.g., canvas size, feature size)
@ Unknown
Mixed or unknown units.
@ MetersInMapUnits
Meters value as Map units.
@ RenderingSubSymbol
Set whenever a sub-symbol of a parent symbol is currently being rendered. Can be used during symbol a...
@ RenderSymbolPreview
The render is for a symbol preview only and map based properties may not be available,...
@ RenderMapTile
Draw map such that there are no problems between adjacent tiles.
@ HighQualityImageTransforms
Enable high quality image transformations, which results in better appearance of scaled or rotated ra...
@ RenderBlocking
Render and load remote sources in the same thread to ensure rendering remote sources (svg and images)...
GradientType
Gradient types.
@ Conical
Conical (polar) gradient.
@ Radial
Radial (circular) gradient.
QFlags< SymbolRenderHint > SymbolRenderHints
Symbol render hints.
SymbolCoordinateReference
Symbol coordinate reference modes.
@ Feature
Relative to feature/shape being rendered.
@ Viewport
Relative to the whole viewport/output device.
QColor valueAsColor(int key, const QgsExpressionContext &context, const QColor &defaultColor=QColor(), bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a color.
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...
A fill symbol layer which renders a marker symbol at the centroid of a polygon geometry.
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 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 number...
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, Qgis::GeosCreationFlags flags=Qgis::GeosCreationFlag::SkipEmptyInteriorRings)
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.
A fill symbol layer which draws a smooth color gradient over a polygon.
void setColorRamp(QgsColorRamp *ramp)
Sets the color ramp used for the gradient fill.
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
QColor color2() const
Returns the color for endpoint of gradient, only used if the gradient color type is set to SimpleTwoC...
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
bool canCauseArtifactsBetweenAdjacentTiles() const override
Returns true if the symbol layer rendering can cause visible artifacts across a single feature when t...
QgsGradientFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
QgsMapUnitScale mapUnitScale() const override
bool mReferencePoint1IsCentroid
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
Qgis::SymbolCoordinateReference coordinateMode() const
Returns the coordinate mode for gradient, which controls how the gradient stops are positioned.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
Qgis::SymbolCoordinateReference mCoordinateMode
QgsGradientFillSymbolLayer(const QColor &color=DEFAULT_SIMPLEFILL_COLOR, const QColor &color2=Qt::white, Qgis::GradientColorSource gradientColorType=Qgis::GradientColorSource::SimpleTwoColor, Qgis::GradientType gradientType=Qgis::GradientType::Linear, Qgis::SymbolCoordinateReference coordinateMode=Qgis::SymbolCoordinateReference::Feature, Qgis::GradientSpread gradientSpread=Qgis::GradientSpread::Pad)
Constructor for QgsGradientFillSymbolLayer.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsGradientFillSymbolLayer using the specified properties map containing symbol propert...
void setMapUnitScale(const QgsMapUnitScale &scale) override
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
Qgis::GradientSpread mGradientSpread
~QgsGradientFillSymbolLayer() override
Qgis::GradientType mGradientType
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QPointF referencePoint1() const
Returns the starting point of gradient fill, in the range [0,0] - [1,1].
Qgis::GradientSpread gradientSpread() const
Returns the gradient spread mode, which controls how the gradient behaves outside of the predefined s...
bool mReferencePoint2IsCentroid
QgsMapUnitScale mOffsetMapUnitScale
Qgis::GradientColorSource gradientColorType() const
Returns the gradient color mode, which controls how gradient color stops are created.
QPointF offset() const
Returns the offset by which polygons will be translated during rendering.
Qgis::GradientColorSource mGradientColorType
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
Qgis::SymbolLayerFlags flags() const override
Returns flags which control the symbol layer's behavior.
QString layerType() const override
Returns a string that represents this layer type.
Qgis::RenderUnit mOffsetUnit
Qgis::GradientType gradientType() const
Returns the type of gradient, e.g., linear or radial.
QPointF referencePoint2() const
Returns the end point of gradient fill, in the range [0,0] - [1,1].
std::unique_ptr< QgsColorRamp > mGradientRamp
QSize originalSize(const QString &path, bool blocking=false) const
Returns the original size (in pixels) of the image at the specified path.
QImage pathAsImage(const QString &path, const QSize size, const bool keepAspectRatio, const double opacity, bool &fitsInCache, bool blocking=false, double targetDpi=96, int frameNumber=-1, bool *isMissing=nullptr)
Returns the specified path rendered as an image.
Base class for fill symbol layers which fill polygons with a repeated image.
QgsMapUnitScale mStrokeWidthMapUnitScale
QgsImageFillSymbolLayer()
Qgis::SymbolCoordinateReference coordinateReference() const
Returns the coordinate reference mode for fill which controls how the top left corner of the image fi...
double mStrokeWidth
Stroke width.
Qgis::SymbolCoordinateReference mCoordinateReference
double dxfWidth(const QgsDxfExport &e, QgsSymbolRenderContext &context) const override
Gets line width.
QgsMapUnitScale mapUnitScale() const override
Qt::PenStyle dxfPenStyle() const override
Gets pen style.
Qgis::RenderUnit mStrokeWidthUnit
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
void setMapUnitScale(const QgsMapUnitScale &scale) override
virtual void applyDataDefinedSettings(QgsSymbolRenderContext &context)
Applies data defined settings prior to generating the fill symbol brush.
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
~QgsImageFillSymbolLayer() override
virtual bool applyBrushTransformFromContext(QgsSymbolRenderContext *context=nullptr) const
Returns true if the image brush should be transformed using the render context's texture origin.
static void multiplyOpacity(QImage &image, double factor, QgsFeedback *feedback=nullptr)
Multiplies opacity of image pixel values by a factor.
static void stackBlur(QImage &image, int radius, bool alphaOnly=false, QgsFeedback *feedback=nullptr)
Performs a stack blur on an image.
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.
static std::unique_ptr< QgsLineString > fromQPolygonF(const QPolygonF &polygon)
Returns a new linestring from a QPolygonF polygon input.
QPolygonF asQPolygonF() const override
Returns a QPolygonF representing the points.
A line symbol type, for rendering LineString and MultiLineString geometries.
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, const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE())
Adds a message to the log instance (and creates it if necessary).
Resolves relative paths into absolute paths and vice versa.
QString writePath(const QString &filename) const
Prepare a filename to save it to the project file.
QString readPath(const QString &filename) const
Turn filename read from the project file to an absolute path.
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
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 fill symbol layer which fills polygons 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 ...
Qgis::SymbolLayerFlags flags() const override
Returns flags which control the symbol layer's behavior.
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
static QgsSymbolLayer * createFromSld(QDomElement &element)
Creates a new QgsRasterFillSymbolLayer from a SLD element.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsRasterFillSymbolLayer from a properties map.
QString layerType() const override
Returns a string that represents this layer type.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QgsRasterFillSymbolLayer(const QString &imageFilePath=QString())
Constructor for QgsRasterFillSymbolLayer, using a raster fill from the specified imageFilePath.
double opacity() const
Returns the opacity for the raster image used in the fill.
~QgsRasterFillSymbolLayer() override
void setOpacity(double opacity)
Sets the opacity for the raster image used in the fill.
QColor color() const override
Returns the "representative" color of the symbol layer.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
QString imageFilePath() const
The path to the raster image used for the fill.
void setImageFilePath(const QString &imagePath)
Sets the path to the raster image used for the fill.
double height() const
Returns the height used for scaling the image used in the fill.
static void resolvePaths(QVariantMap &properties, const QgsPathResolver &pathResolver, bool saving)
Turns relative paths in properties map to absolute when reading and vice versa when writing.
QPointF offset() const
Returns the offset for the fill.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer's subsymbol. takes ownership of the passed symbol.
QgsRasterFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
bool applyBrushTransformFromContext(QgsSymbolRenderContext *context=nullptr) const override
Returns true if the image brush should be transformed using the render context's texture origin.
void setCoordinateMode(Qgis::SymbolCoordinateReference mode)
Set the coordinate mode for fill.
A rectangle specified with double values.
Contains information about the context of a rendering operation.
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.
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 fill symbol layer which fills polygons 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.
A fill symbol layer which applies a gradient from the outer edges of a symbol to the inside.
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
QgsShapeburstFillSymbolLayer(const QColor &color=DEFAULT_SIMPLEFILL_COLOR, const QColor &color2=Qt::white, Qgis::GradientColorSource colorType=Qgis::GradientColorSource::SimpleTwoColor, int blurRadius=0, bool useWholeShape=true, double maxDistance=5)
Constructor for QgsShapeburstFillSymbolLayer.
QgsShapeburstFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
~QgsShapeburstFillSymbolLayer() override
int blurRadius() const
Returns the blur radius, which controls the amount of blurring applied to the fill.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
QColor color2() const
Returns the color used for the endpoint of the shapeburst fill.
void setMapUnitScale(const QgsMapUnitScale &scale) override
QgsMapUnitScale mapUnitScale() const override
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
bool canCauseArtifactsBetweenAdjacentTiles() const override
Returns true if the symbol layer rendering can cause visible artifacts across a single feature when t...
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsShapeburstFillSymbolLayer using the specified properties map containing symbol prope...
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
QPointF offset() const
Returns the offset for the shapeburst fill.
bool useWholeShape() const
Returns whether the shapeburst fill is set to cover the entire shape.
bool ignoreRings() const
Returns whether the shapeburst fill is set to ignore polygon interior rings.
double maxDistance() const
Returns the maximum distance from the shape's boundary which is shaded.
Qgis::SymbolLayerFlags flags() const override
Returns flags which control the symbol layer's behavior.
QString layerType() const override
Returns a string that represents this layer type.
Qgis::GradientColorSource colorType() const
Returns the color mode used for the shapeburst fill.
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
void setColorRamp(QgsColorRamp *ramp)
Sets the color ramp used to draw the shapeburst fill.
Renders polygons using a single fill and stroke color.
QgsSimpleFillSymbolLayer(const QColor &color=DEFAULT_SIMPLEFILL_COLOR, Qt::BrushStyle style=DEFAULT_SIMPLEFILL_STYLE, const QColor &strokeColor=DEFAULT_SIMPLEFILL_BORDERCOLOR, Qt::PenStyle strokeStyle=DEFAULT_SIMPLEFILL_BORDERSTYLE, double strokeWidth=DEFAULT_SIMPLEFILL_BORDERWIDTH, Qt::PenJoinStyle penJoinStyle=DEFAULT_SIMPLEFILL_JOINSTYLE)
double dxfWidth(const QgsDxfExport &e, QgsSymbolRenderContext &context) const override
Gets line width.
Qt::PenJoinStyle penJoinStyle() const
QColor strokeColor() const override
Returns the stroke color for the symbol layer.
QColor dxfBrushColor(QgsSymbolRenderContext &context) const override
Gets brush/fill color.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
Qt::BrushStyle dxfBrushStyle() const override
Gets brush/fill style.
QString ogrFeatureStyle(double mmScaleFactor, double mapUnitScaleFactor) const override
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
Qgis::SymbolLayerFlags flags() const override
Returns flags which control the symbol layer's behavior.
Qgis::RenderUnit mOffsetUnit
~QgsSimpleFillSymbolLayer() override
void toSld(QDomDocument &doc, QDomElement &element, const QVariantMap &props) const override
Saves the symbol layer as SLD.
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
QColor dxfColor(QgsSymbolRenderContext &context) const override
Gets color.
QColor fillColor() const override
Returns the fill color for the symbol layer.
Qt::PenStyle strokeStyle() const
QString layerType() const override
Returns a string that represents this layer type.
double dxfAngle(QgsSymbolRenderContext &context) const override
Gets angle.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QgsMapUnitScale mOffsetMapUnitScale
double strokeWidth() const
Qgis::RenderUnit mStrokeWidthUnit
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
QPointF offset() const
Returns the offset by which polygons will be translated during rendering.
Qt::PenStyle dxfPenStyle() const override
Gets pen style.
QgsMapUnitScale mStrokeWidthMapUnitScale
QImage toTiledPatternImage() const override
Renders the symbol layer as an image that can be used as a seamless pattern fill for polygons,...
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
QgsSimpleFillSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
Qt::PenStyle mStrokeStyle
QgsMapUnitScale mapUnitScale() const override
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
Qt::PenJoinStyle mPenJoinStyle
Qt::BrushStyle mBrushStyle
void setMapUnitScale(const QgsMapUnitScale &scale) override
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsSimpleFillSymbolLayer using the specified properties map containing symbol propertie...
static QgsSymbolLayer * createFromSld(QDomElement &element)
Holds SLD export options and other information related to SLD export of a QGIS layer style.
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.
Contains utility functions for working with symbols and symbol layers.
static bool rotationFromSldElement(QDomElement &element, QString &rotationFunc)
static Qgis::MarkerClipMode decodeMarkerClipMode(const QString &string, bool *ok=nullptr)
Decodes a string representing a marker clip mode.
static QString encodePenStyle(Qt::PenStyle style)
static Qt::PenJoinStyle decodePenJoinStyle(const QString &str)
static QString encodeMapUnitScale(const QgsMapUnitScale &mapUnitScale)
static QgsStringMap evaluatePropertiesMap(const QMap< QString, QgsProperty > &propertiesMap, const QgsExpressionContext &context)
Evaluates a map of properties using the given context and returns a variant map with evaluated expres...
static bool displacementFromSldElement(QDomElement &element, QPointF &offset)
static QPointF polygonCentroid(const QPolygonF &points)
Calculate the centroid point of a QPolygonF.
static QString encodeBrushStyle(Qt::BrushStyle style)
static QString svgSymbolPathToName(const QString &path, const QgsPathResolver &pathResolver)
Determines an SVG symbol's name from its path.
static void externalGraphicToSld(QDomDocument &doc, QDomElement &element, const QString &path, const QString &mime, const QColor &color, double size=-1)
static QPointF polygonPointOnSurface(const QPolygonF &points, const QVector< QPolygonF > *rings=nullptr)
Calculate a point on the surface of a QPolygonF.
static QPointF toPoint(const QVariant &value, bool *ok=nullptr)
Converts a value to a point.
static void multiplyImageOpacity(QImage *image, qreal opacity)
Multiplies opacity of image pixel values with a (global) transparency value.
static QgsMapUnitScale decodeMapUnitScale(const QString &str)
static double rescaleUom(double size, Qgis::RenderUnit unit, const QVariantMap &props)
Rescales the given size based on the uomScale found in the props, if any is found,...
static std::unique_ptr< QgsSymbolLayer > createMarkerLayerFromSld(QDomElement &element)
Creates a new marker layer from a SLD DOM element.
static QString ogrFeatureStylePen(double width, double mmScaleFactor, double mapUnitsScaleFactor, const QColor &c, Qt::PenJoinStyle joinStyle=Qt::MiterJoin, Qt::PenCapStyle capStyle=Qt::FlatCap, double offset=0.0, const QVector< qreal > *dashPattern=nullptr)
Create ogr feature style string for pen.
static bool externalGraphicFromSld(QDomElement &element, QString &path, QString &mime, QColor &color, double &size)
static void parametricSvgToSld(QDomDocument &doc, QDomElement &graphicElem, const QString &path, const QColor &fillColor, double size, const QColor &strokeColor, double strokeWidth)
Encodes a reference to a parametric SVG into SLD, as a succession of parametric SVG using URL paramet...
static bool lineFromSld(QDomElement &element, Qt::PenStyle &penStyle, QColor &color, double &width, Qt::PenJoinStyle *penJoinStyle=nullptr, Qt::PenCapStyle *penCapStyle=nullptr, QVector< qreal > *customDashPattern=nullptr, double *dashOffset=nullptr)
static std::unique_ptr< QgsSymbolLayer > createLineLayerFromSld(QDomElement &element)
Creates a new line layer from a SLD DOM element.
static QString ogrFeatureStyleBrush(const QColor &fillColr)
Create ogr feature style string for brush.
static QString encodeLineClipMode(Qgis::LineClipMode mode)
Encodes a line clip mode to a string.
static Qgis::LineClipMode decodeLineClipMode(const QString &string, bool *ok=nullptr)
Decodes a string representing a line clip mode.
static QPointF pointOnLineWithDistance(QPointF startPoint, QPointF directionPoint, double distance)
Returns a point on the line from startPoint to directionPoint that is a certain distance away from th...
static QSize tileSize(int width, int height, double &angleRad)
Calculate the minimum size in pixels of a symbol tile given the symbol width and height and the symbo...
static Qt::BrushStyle decodeBrushStyle(const QString &str)
static 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)
Extracts properties from an SLD marker definition.
static void createDisplacementElement(QDomDocument &doc, QDomElement &element, QPointF offset)
static QString svgSymbolNameToPath(const QString &name, const QgsPathResolver &pathResolver)
Determines an SVG symbol's path from its name.
static QString encodeColor(const QColor &color)
static bool fillFromSld(QDomElement &element, Qt::BrushStyle &brushStyle, QColor &color)
static 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 QString encodePenJoinStyle(Qt::PenJoinStyle style)
static QgsStringMap getVendorOptionList(QDomElement &element)
static QPointF decodePoint(const QString &string)
Decodes a QSizeF from a string.
static QString encodeCoordinateReference(Qgis::SymbolCoordinateReference coordinateReference)
Encodes a symbol coordinate reference mode to a string.
static QString encodeMarkerClipMode(Qgis::MarkerClipMode mode)
Encodes a marker clip mode to a string.
Abstract base class for symbol layers.
virtual bool setSubSymbol(QgsSymbol *symbol)
Sets layer's subsymbol. takes ownership of the passed symbol.
bool shouldRenderUsingSelectionColor(const QgsSymbolRenderContext &context) const
Returns true if the symbol layer should be rendered using the selection color from the render context...
Qgis::SymbolType type() const
virtual QColor fillColor() const
Returns the fill color for the symbol layer.
static const bool SELECTION_IS_OPAQUE
Whether styles for selected features ignore symbol alpha.
bool installMasks(QgsRenderContext &context, bool recursive, const QRectF &rect=QRectF())
When rendering, install masks on context painter.
void removeMasks(QgsRenderContext &context, bool recursive)
When rendering, remove previously installed masks from context painter if recursive is true masks are...
virtual QSet< QString > usedAttributes(const QgsRenderContext &context) const
Returns the set of attributes referenced by the layer.
void copyDataDefinedProperties(QgsSymbolLayer *destLayer) const
Copies all data defined properties of this layer to another symbol layer.
@ GradientType
Gradient fill type.
@ SecondaryColor
Secondary color (eg for gradient fills)
@ File
Filename, eg for svg files.
@ GradientReference2Y
Gradient reference point 2 y.
@ GradientReference1X
Gradient reference point 1 x.
@ OffsetY
Vertical offset.
@ OffsetX
Horizontal offset.
@ GradientReference1Y
Gradient reference point 1 y.
@ GradientSpread
Gradient spread mode.
@ ShapeburstMaxDistance
Shapeburst fill from edge distance.
@ StrokeStyle
Stroke style (eg solid, dashed)
@ DistanceY
Vertical distance between points.
@ DensityArea
Density area.
@ ClipPoints
Whether markers should be clipped to polygon boundaries.
@ LineClipping
Line clipping mode.
@ ShapeburstIgnoreRings
Shapeburst ignore rings.
@ ShapeburstUseWholeShape
Shapeburst use whole shape.
@ DisplacementX
Horizontal displacement.
@ CoordinateMode
Gradient coordinate mode.
@ FillStyle
Fill style (eg solid, dots)
@ GradientReference2X
Gradient reference point 2 x.
@ StrokeColor
Stroke color.
@ BlurRadius
Shapeburst blur radius.
@ MarkerClipping
Marker clipping mode.
@ RandomSeed
Random number seed.
@ LineAngle
Line angle, or angle of hash lines for hash line symbols.
@ JoinStyle
Line join style.
@ RandomOffsetY
Random offset Y.
@ DisplacementY
Vertical displacement.
@ DistanceX
Horizontal distance between points.
@ GradientReference1IsCentroid
Gradient reference point 1 is centroid.
@ StrokeWidth
Stroke width.
@ GradientReference2IsCentroid
Gradient reference point 2 is centroid.
@ LineDistance
Distance between lines, or length of lines for hash line symbols.
@ RandomOffsetX
Random offset X.
void restoreOldDataDefinedProperties(const QVariantMap &stringMap)
Restores older data defined properties from string map.
virtual double estimateMaxBleed(const QgsRenderContext &context) const
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
static const bool SELECT_FILL_BORDER
Whether fill styles for selected features also highlight symbol stroke.
virtual QString layerType() const =0
Returns a string that represents this layer type.
virtual QColor color() const
Returns the "representative" color of the symbol layer.
virtual QColor strokeColor() const
Returns the stroke color for the symbol layer.
void copyPaintEffect(QgsSymbolLayer *destLayer) const
Copies paint effect of this layer to another symbol layer.
virtual Qgis::SymbolLayerFlags flags() const
Returns flags which control the symbol layer's behavior.
QgsPropertyCollection mDataDefinedProperties
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the symbol layer's property collection, used for data defined overrides.
static const bool SELECT_FILL_STYLE
Whether fill styles for selected features uses symbol layer style.
virtual bool hasDataDefinedProperties() const
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
Encapsulates the context in which a symbol is being rendered.
const QgsFeature * feature() const
Returns the current feature being rendered.
QgsFields fields() const
Fields of the layer.
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for data defined symbology.
bool forceVectorRendering() const
Returns true if symbol must be rendered using vector methods, and optimisations like pre-rendered ima...
qreal opacity() const
Returns the opacity for the symbol.
QgsRenderContext & renderContext()
Returns a reference to the context's render context.
Abstract base class for all rendered symbols.
QColor color() const
Returns the symbol's color.
Qgis::SymbolType type() const
Returns the symbol's type.
double interval() const
Returns the interval between individual symbols.
const QgsMapUnitScale & intervalMapUnitScale() const
Returns the map unit scale for the interval between symbols.
void setInterval(double interval)
Sets the interval between individual symbols.
Qgis::RenderUnit intervalUnit() const
Returns the units for the interval between symbols.
static Q_INVOKABLE Qgis::RenderUnit decodeRenderUnit(const QString &string, bool *ok=nullptr)
Decodes a render unit from a string.
static Q_INVOKABLE QString encodeUnit(Qgis::DistanceUnit unit)
Encodes a distance unit to a string.
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
QMap< QString, QString > QgsStringMap
#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.