32#include "moc_qgscolorramplegendnode.cpp"
34using namespace Qt::StringLiterals;
37 QgsLayerTreeLayer *nodeLayer,
QgsColorRamp *
ramp,
const QString &minimumLabel,
const QString &maximumLabel, QObject *parent,
const QString &key,
const QString &parentKey
42 , mParentKey( parentKey )
44 mSettings.setMinimumLabel( minimumLabel );
45 mSettings.setMaximumLabel( maximumLabel );
56 , mMinimumValue( minimumValue )
57 , mMaximumValue( maximumValue )
59 , mParentKey( parentKey )
69 connect( nodeLayer, &QObject::destroyed,
this, [
this]() {
mLayerNode =
nullptr; } );
87QString QgsColorRampLegendNode::labelForMinimum()
const
96QString QgsColorRampLegendNode::labelForMaximum()
const
98 if ( !mSettings.maximumLabel().isEmpty() )
99 return mSettings.prefix() + mSettings.maximumLabel() + mSettings.suffix();
101 const QgsNumericFormatContext numericContext;
102 return mSettings.prefix() + mSettings.numericFormat()->formatDouble( mMaximumValue, numericContext ) + mSettings.suffix();
107 if ( role == Qt::DisplayRole )
111 else if ( role == Qt::EditRole )
115 else if ( role == Qt::DecorationRole )
117 if ( mPixmap.isNull() )
119 const QFont font =
data( Qt::FontRole ).value< QFont >();
121 const QString minLabel = labelForMinimum();
122 const QString maxLabel = labelForMaximum();
124 const QFontMetrics fm( font );
126 const QRect minBoundingRect = fm.boundingRect( minLabel );
127 const QRect maxBoundingRect = fm.boundingRect( maxLabel );
130 double devicePixelRatio = 1;
136 const double minLabelWidth = minBoundingRect.width() * devicePixelRatio;
137 const double maxLabelWidth = maxBoundingRect.width() * devicePixelRatio;
138 const double maxTextWidth = std::max( minLabelWidth, maxLabelWidth );
139 const double labelGapFromRamp = fm.boundingRect( u
"x"_s ).width() * devicePixelRatio;
140 const double extraAllowance = labelGapFromRamp * 0.4;
143 switch ( mSettings.orientation() )
146 labelRect = QRectF( ( mIconSize.width() + labelGapFromRamp ) / devicePixelRatio, 0, ( maxTextWidth + extraAllowance ) / devicePixelRatio, mIconSize.height() / devicePixelRatio );
147 mPixmap = QPixmap( mIconSize.width() + maxTextWidth + labelGapFromRamp + extraAllowance, mIconSize.height() );
148 rampSize = mIconSize;
154 ( mIconSize.height() + labelGapFromRamp ) / devicePixelRatio,
155 std::max(
static_cast<double>( mIconSize.width() ), minLabelWidth + maxLabelWidth + labelGapFromRamp ) / devicePixelRatio,
156 ( std::max( minBoundingRect.height() * devicePixelRatio, maxBoundingRect.height() * devicePixelRatio ) + extraAllowance ) / devicePixelRatio
158 mPixmap = QPixmap( std::max(
static_cast< double >( mIconSize.width() ), minLabelWidth + maxLabelWidth + labelGapFromRamp ), mIconSize.height() + maxTextWidth + labelGapFromRamp + extraAllowance );
159 rampSize = QSize( labelRect.width(), mIconSize.height() );
163 mPixmap.fill( Qt::transparent );
164 mPixmap.setDevicePixelRatio( devicePixelRatio );
174 mSettings.orientation(),
181 pix = QPixmap( rampSize );
182 pix.fill( Qt::transparent );
185 pix.setDevicePixelRatio( devicePixelRatio );
187 QPainter p( &mPixmap );
188 p.drawPixmap( 0, 0, pix );
190 p.setPen( qApp->palette().color( QPalette::Text ) );
192 switch ( mSettings.orientation() )
229 std::unique_ptr< QgsRenderContext > tempRenderContext;
234 tempRenderContext = std::make_unique< QgsRenderContext >();
237 tempRenderContext->setScaleFactor(
settings.dpi() / 25.4 );
238 tempRenderContext->setRendererScale(
settings.mapScale() );
240 tempRenderContext->setMapToPixel(
QgsMapToPixel( 1 / (
settings.mmPerMapUnit() * tempRenderContext->scaleFactor() ) ) );
243 tempRenderContext->setPainter( ctx ? ctx->
painter :
nullptr );
248 tempRenderContext->setExpressionContext( expContext );
249 context = tempRenderContext.get();
253 const QString minLabel = labelForMinimum();
254 const QString maxLabel = labelForMaximum();
259 double minHeightMm = 0;
260 double minWidthMm = 0;
261 double rampHeight = 0;
262 double rampWidth = 0;
263 switch ( mSettings.orientation() )
268 rampHeight = ctx && ctx->
patchSize.height() > 0 ? std::max( minHeightMm / 2, ctx->
patchSize.height() ) : std::max( minHeightMm,
settings.symbolSize().height() );
269 rampWidth = patchWidth;
275 rampHeight = patchHeight;
276 rampWidth = std::max( minWidthMm, patchWidth );
282 const double currentYCoord = ctx->
top;
290 opacity = layer->opacity();
295 double rampLeftMm = 0;
296 const double rampTopMm = currentYCoord;
297 switch (
settings.symbolAlignment() )
309 p->scale( 1.0 / dotsPerMM, 1.0 / dotsPerMM );
311 QLinearGradient gradient;
312 switch ( mSettings.orientation() )
316 const double gradientTop = rampTopMm * dotsPerMM;
317 const double gradientBottom = gradientTop + rampHeight * dotsPerMM;
325 const double gradientLeft = rampLeftMm * dotsPerMM;
326 const double gradientRight = gradientLeft + rampWidth * dotsPerMM;
344 pen.setColor(
settings.rasterStrokeColor() );
345 pen.setWidthF(
settings.rasterStrokeWidth() * dotsPerMM );
346 pen.setJoinStyle( Qt::MiterJoin );
351 ctx->
painter->setPen( Qt::NoPen );
354 p->setBrush( QBrush( gradient ) );
355 p->drawRect( rampLeftMm * dotsPerMM, rampTopMm * dotsPerMM, rampWidth * dotsPerMM, rampHeight * dotsPerMM );
358 double labelHeight = 0;
359 if ( mSettings.orientation() == Qt::Horizontal )
364 const double currentYCoord = ctx->
top;
373 p->scale( 1.0 / dotsPerMM, 1.0 / dotsPerMM );
375 double labelXMin = 0;
376 double labelXMax = 0;
380 const double labelYMin = currentYCoord
386 switch (
settings.symbolAlignment() )
400 const QRectF textRect( labelXMin * dotsPerMM, labelYMin * dotsPerMM, ( labelXMax - labelXMin ) * dotsPerMM, labelHeight * dotsPerMM );
416 return QSizeF( rampWidth, rampHeight + labelHeight );
421 if ( !mRamp || mSettings.orientation() == Qt::Horizontal )
428 std::unique_ptr< QgsRenderContext > tempRenderContext;
433 tempRenderContext = std::make_unique< QgsRenderContext >();
436 tempRenderContext->setScaleFactor(
settings.dpi() / 25.4 );
437 tempRenderContext->setRendererScale(
settings.mapScale() );
439 tempRenderContext->setMapToPixel(
QgsMapToPixel( 1 / (
settings.mmPerMapUnit() * tempRenderContext->scaleFactor() ) ) );
442 tempRenderContext->setPainter( ctx ? ctx->
painter :
nullptr );
447 tempRenderContext->setExpressionContext( expContext );
448 context = tempRenderContext.get();
453 const QString minLabel = labelForMinimum();
454 const QString maxLabel = labelForMaximum();
456 const double rampHeight = symbolSize.height();
457 const double rampWidth = symbolSize.width();
458 double textWidth = 0;
459 double textHeight = 0;
463 const double currentYCoord = ctx->
top;
472 p->scale( 1.0 / dotsPerMM, 1.0 / dotsPerMM );
474 double labelXMin = 0;
475 double labelXMax = 0;
476 switch (
settings.symbolAlignment() )
499 const QRectF textRect( labelXMin * dotsPerMM, currentYCoord * dotsPerMM, ( labelXMax - labelXMin ) * dotsPerMM, rampHeight * dotsPerMM );
525 textHeight = rampHeight;
528 return QSizeF( textWidth, textHeight );
538 const QPixmap icon =
data( Qt::DecorationRole ).value<QPixmap>();
540 if ( !icon.isNull() )
542 const QImage image( icon.toImage() );
543 QByteArray byteArray;
544 QBuffer buffer( &byteArray );
545 image.save( &buffer,
"PNG" );
546 const QString base64 = QString::fromLatin1( byteArray.toBase64().data() );
547 json[u
"icon"_s] = base64;
550 json[u
"min"_s] = mMinimumValue;
551 json[u
"max"_s] = mMaximumValue;
@ PreferVector
Prefer vector-based rendering, when the result will still be visually near-identical to a raster-base...
@ Symbol
Symbol icon (excluding label).
@ SymbolLabel
Symbol label (excluding icon).
@ Rectangle
Text within rectangle layout mode.
@ Antialiasing
Use antialiasing while drawing.
Settings for a color ramp legend node.
const QgsNumericFormat * numericFormat() const
Returns the numeric format used for numbers in the scalebar.
QString suffix() const
Returns the suffix to show after legend text.
@ MaximumToMinimum
Maximum value on bottom, minimum value on top.
@ MinimumToMaximum
Minimum value on bottom, maximum value on top.
QString prefix() const
Returns the prefix to show before legend text.
Qt::Orientation orientation() const
Returns the ramp orientation (i.e.
QString minimumLabel() const
Returns the label for the minimum value on the ramp.
QSizeF drawSymbolText(const QgsLegendSettings &settings, ItemContext *ctx, QSizeF symbolSize) const override
Draws label on the right side of the item.
const QgsColorRamp * ramp() const
Returns the color ramp used by the node.
QSize iconSize() const
Returns the icon size, which is how large the ramp will render in a layer tree widget.
void setSettings(const QgsColorRampLegendNodeSettings &settings)
Sets the node's settings.
QgsColorRampLegendNode(QgsLayerTreeLayer *nodeLayer, QgsColorRamp *ramp, const QString &minimumLabel, const QString &maximumLabel, QObject *parent=nullptr, const QString &key=QString(), const QString &parentKey=QString())
Constructor for QgsColorRampLegendNode.
QJsonObject exportSymbolToJson(const QgsLegendSettings &settings, const QgsRenderContext &context) const override
Adds a symbol in base64 string within a JSON object with the key "icon".
void invalidateDisplayData() override
Invalidates cached display data for the node.
QgsColorRampLegendNodeSettings settings() const
Returns the node's settings.
QVariant data(int role) const override
Returns data associated with the item. Must be implemented in derived class.
QSizeF drawSymbol(const QgsLegendSettings &settings, ItemContext *ctx, double itemHeight) const override
Draws symbol on the left side of the item.
Abstract base class for color ramps.
static QString typeString()
Returns the string identifier for QgsCptCityColorRamp.
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer's project and layer.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void appendScopes(const QList< QgsExpressionContextScope * > &scopes)
Appends a list of scopes to the end of the context.
Gradient color ramp, which smoothly interpolates between two colors and also supports optional extra ...
static QString typeString()
Returns the string identifier for QgsGradientColorRamp.
void addStopsToGradient(QGradient *gradient, double opacity=1) const
Copy color ramp stops to a QGradient.
Layer tree node points to a map layer.
@ ColorRampLegend
Color ramp legend.
@ ParentRuleKey
Rule key of the parent legend node - for legends with tree hierarchy (QString). Added in 2....
@ NodeType
Type of node. Added in 3.16.
@ RuleKey
Rule key of the node (QString).
QgsLayerTreeLayer * mLayerNode
QgsLayerTreeModelLegendNode(QgsLayerTreeLayer *nodeL, QObject *parent=nullptr)
Construct the node with pointer to its parent layer node.
QgsLayerTreeModel * model() const
Returns pointer to model owning this legend node.
QgsLayerTreeLayer * layerNode() const
Returns pointer to the parent layer node.
QSet< QgsScreenProperties > targetScreenProperties() const
Returns the target screen properties to use when generating icons.
static int scaleIconSize(int standardSize)
Scales an layer tree model icon size to compensate for display pixel density, making the icon size hi...
Stores the appearance and layout settings for legend drawing with QgsLegendRenderer.
Base class for all map layer types.
Perform transforms between map coordinates and device coordinates.
A context for numeric formats.
Contains information about the context of a rendering operation.
double scaleFactor() const
Returns the scaling factor for the render to convert painter units to physical sizes.
void setPainterFlagsUsingContext(QPainter *painter=nullptr) const
Sets relevant flags on a destination painter, using the flags and settings currently defined for the ...
Scoped object for saving and restoring a QPainter object's state.
Stores properties relating to a screen.
double devicePixelRatio() const
Returns the ratio between physical pixels and device-independent pixels for the screen.
bool isValid() const
Returns true if the properties are valid.
static QPixmap colorRampPreviewPixmap(QgsColorRamp *ramp, QSize size, int padding=0, Qt::Orientation direction=Qt::Horizontal, bool flipDirection=false, bool drawTransparentBackground=true)
Returns a pixmap preview for a color ramp.
Container for all settings relating to text rendering.
bool isValid() const
Returns true if the format is valid.
static double textWidth(const QgsRenderContext &context, const QgsTextFormat &format, const QStringList &textLines, QFontMetricsF *fontMetrics=nullptr)
Returns the width of a text based on a given format.
static void drawText(const QRectF &rect, double rotation, Qgis::TextHorizontalAlignment alignment, const QStringList &textLines, QgsRenderContext &context, const QgsTextFormat &format, bool drawAsOutlines=true, Qgis::TextVerticalAlignment vAlignment=Qgis::TextVerticalAlignment::Top, Qgis::TextRendererFlags flags=Qgis::TextRendererFlags(), Qgis::TextLayoutMode mode=Qgis::TextLayoutMode::Rectangle)
Draws text within a rectangle using the specified settings.
static double textHeight(const QgsRenderContext &context, const QgsTextFormat &format, const QStringList &textLines, Qgis::TextLayoutMode mode=Qgis::TextLayoutMode::Point, QFontMetricsF *fontMetrics=nullptr, Qgis::TextRendererFlags flags=Qgis::TextRendererFlags(), double maxLineWidth=0)
Returns the height of a text based on a given format.
static Qgis::TextHorizontalAlignment convertQtHAlignment(Qt::Alignment alignment)
Converts a Qt horizontal alignment flag to a Qgis::TextHorizontalAlignment value.
#define Q_NOWARN_DEPRECATED_POP
#define Q_NOWARN_DEPRECATED_PUSH
QPainter * painter
Painter.
double top
Top y-position of legend item.
double maxSiblingSymbolWidth
Largest symbol width, considering all other sibling legend components associated with the current com...
QSizeF patchSize
Symbol patch size to render for the node.
double columnLeft
Left side of current legend column.
double columnRight
Right side of current legend column.
Q_NOWARN_DEPRECATED_POP QgsRenderContext * context
Render context, if available.