39#include "moc_qgsmaplayerlegend.cpp"
41using namespace Qt::StringLiterals;
56 QDomElement elem = doc.createElement( u
"legend"_s );
59 elem.setAttribute( u
"excludeByDefault"_s, u
"1"_s );
90 const auto constOrder = order;
91 for (
const int id : constOrder )
92 orderStr << QString::number(
id );
93 const QString str = orderStr.isEmpty() ? u
"empty"_s : orderStr.join(
','_L1 );
102 const int numNodes = lst.count();
111 QgsDebugError( u
"Legend node order manipulation is invalid without existing legend"_s );
115 const int numNodes = _originalLegendNodeCount( nodeLayer );
118 order.reserve( numNodes );
119 for (
int i = 0; i < numNodes; ++i )
126 const QString orderStr = nodeLayer->
customProperty( u
"legend/node-order"_s ).toString();
128 if ( orderStr.isEmpty() )
129 return _makeNodeOrder( nodeLayer );
131 if ( orderStr ==
"empty"_L1 )
134 const int numNodes = _originalLegendNodeCount( nodeLayer );
137 const auto constSplit = orderStr.split(
',' );
138 for (
const QString &item : constSplit )
141 const int id = item.toInt( &ok );
142 if ( !ok || id < 0 || id >= numNodes )
143 return _makeNodeOrder( nodeLayer );
158 nodeLayer->
setCustomProperty(
"legend/label-" + QString::number( originalIndex ), newLabel );
163 return nodeLayer->
customProperty(
"legend/label-" + QString::number( originalIndex ) ).toString();
168 return nodeLayer->
customProperties().contains(
"legend/label-" + QString::number( originalIndex ) );
173 QDomDocument patchDoc;
174 QDomElement patchElem = patchDoc.createElement( u
"patch"_s );
176 patchDoc.appendChild( patchElem );
177 nodeLayer->
setCustomProperty(
"legend/patch-shape-" + QString::number( originalIndex ), patchDoc.toString() );
182 const QString patchDef = nodeLayer->
customProperty(
"legend/patch-shape-" + QString::number( originalIndex ) ).toString();
183 if ( patchDef.isEmpty() )
186 QDomDocument doc( u
"patch"_s );
187 doc.setContent( patchDef );
195 if ( size.isValid() )
203 const QString size = nodeLayer->
customProperty(
"legend/symbol-size-" + QString::number( originalIndex ) ).toString();
204 if ( size.isEmpty() )
218 doc.appendChild( elem );
219 nodeLayer->
setCustomProperty(
"legend/custom-symbol-" + QString::number( originalIndex ), doc.toString() );
227 const QString symbolDef = nodeLayer->
customProperty(
"legend/custom-symbol-" + QString::number( originalIndex ) ).toString();
228 if ( symbolDef.isEmpty() )
232 doc.setContent( symbolDef );
233 const QDomElement elem = doc.documentElement();
248 QDomElement elem = doc.createElement( u
"rampSettings"_s );
249 settings->
writeXml( doc, elem, rwContext );
250 doc.appendChild( elem );
251 nodeLayer->
setCustomProperty(
"legend/custom-ramp-settings-" + QString::number( originalIndex ), doc.toString() );
254 nodeLayer->
removeCustomProperty(
"legend/custom-ramp-settings-" + QString::number( originalIndex ) );
259 const QString settingsDef = nodeLayer->
customProperty(
"legend/custom-ramp-settings-" + QString::number( originalIndex ) ).toString();
260 if ( settingsDef.isEmpty() )
264 doc.setContent( settingsDef );
265 const QDomElement elem = doc.documentElement();
271 settings.
readXml( elem, rwContext );
277 if ( columnBreakBeforeNode )
278 nodeLayer->
setCustomProperty(
"legend/column-break-" + QString::number( originalIndex ), u
"1"_s );
285 return nodeLayer->
customProperty(
"legend/column-break-" + QString::number( originalIndex ) ).toInt();
292 const auto constNodes = nodes;
296 if ( !userLabel.isNull() )
302 symbolNode->setPatchShape( shape );
311 colorRampNode->setSettings( *settings );
316 if ( userSize.isValid() )
332 QList<QgsLayerTreeModelLegendNode *> newOrder;
333 QSet<int> usedIndices;
334 const auto constOrder = order;
335 for (
const int idx : constOrder )
337 if ( usedIndices.contains( idx ) )
343 newOrder << nodes[idx];
348 for (
int i = 0; i < nodes.count(); ++i )
350 if ( !usedIndices.contains( i ) )
371 QList<QgsLayerTreeModelLegendNode *> nodes;
375 const QString placeholderImage = mLayer->legendPlaceholderImage();
376 if ( !placeholderImage.isEmpty() )
388 if ( nodeLayer->
customProperty( u
"showFeatureCount"_s, 0 ).toBool() )
389 mLayer->countSymbolFeatures();
397 const QList<QgsLayerTreeModelLegendNode *> rendererNodes = r->
createLegendNodes( nodeLayer );
403 if ( mTextOnSymbolEnabled && mTextOnSymbolContent.contains( ruleKey ) )
405 legendNode->setTextOnSymbolLabel( mTextOnSymbolContent.value( ruleKey ) );
406 legendNode->setTextOnSymbolTextFormat( mTextOnSymbolTextFormat );
412 if ( nodes.count() == 1 && nodes[0]->data( Qt::EditRole ).toString().isEmpty() && qobject_cast< QgsSymbolLegendNode * >( nodes[0] ) )
413 nodes[0]->setEmbeddedInParent(
true );
415 if ( mLayer->diagramsEnabled() )
417 const auto constLegendItems = mLayer->diagramRenderer()->legendItems( nodeLayer );
424 if ( mLayer->labelsEnabled() && mShowLabelLegend )
430 for (
int i = 0; i < pList.size(); ++i )
435 if ( ruleBasedLabeling && ruleBasedLabeling->
rootRule() )
445 nodes.append( node );
457 mTextOnSymbolEnabled =
false;
459 mTextOnSymbolContent.clear();
461 mShowLabelLegend = elem.attribute( u
"showLabelLegend"_s, u
"0"_s ).compare( u
"1"_s, Qt::CaseInsensitive ) == 0;
463 const QDomElement tosElem = elem.firstChildElement( u
"text-on-symbol"_s );
464 if ( !tosElem.isNull() )
466 mTextOnSymbolEnabled =
true;
467 const QDomElement tosFormatElem = tosElem.firstChildElement( u
"text-style"_s );
468 mTextOnSymbolTextFormat.readXml( tosFormatElem, context );
469 const QDomElement tosContentElem = tosElem.firstChildElement( u
"content"_s );
470 QDomElement tosContentItemElem = tosContentElem.firstChildElement( u
"item"_s );
471 while ( !tosContentItemElem.isNull() )
473 mTextOnSymbolContent.insert( tosContentItemElem.attribute( u
"key"_s ), tosContentItemElem.attribute( u
"value"_s ) );
474 tosContentItemElem = tosContentItemElem.nextSiblingElement( u
"item"_s );
482 elem.setAttribute( u
"type"_s, u
"default-vector"_s );
483 elem.setAttribute( u
"showLabelLegend"_s, mShowLabelLegend );
485 if ( mTextOnSymbolEnabled )
487 QDomElement tosElem = doc.createElement( u
"text-on-symbol"_s );
488 const QDomElement tosFormatElem = mTextOnSymbolTextFormat.writeXml( doc, context );
489 tosElem.appendChild( tosFormatElem );
490 QDomElement tosContentElem = doc.createElement( u
"content"_s );
491 for (
auto it = mTextOnSymbolContent.constBegin(); it != mTextOnSymbolContent.constEnd(); ++it )
493 QDomElement tosContentItemElem = doc.createElement( u
"item"_s );
494 tosContentItemElem.setAttribute( u
"key"_s, it.key() );
495 tosContentItemElem.setAttribute( u
"value"_s, it.value() );
496 tosContentElem.appendChild( tosContentItemElem );
498 tosElem.appendChild( tosContentElem );
499 elem.appendChild( tosElem );
517 QList<QgsLayerTreeModelLegendNode *> nodes;
520 if ( mLayer->dataProvider() && mLayer->dataProvider()->supportsLegendGraphic() )
525 const QString placeholderImage = mLayer->legendPlaceholderImage();
526 if ( !placeholderImage.isEmpty() )
532 else if ( mLayer->renderer() )
533 nodes.append( mLayer->renderer()->createLegendNodes( nodeLayer ) );
547 QList<QgsLayerTreeModelLegendNode *> nodes;
555 if ( indexScalar > -1 && indexVector > -1 && indexScalar != indexVector )
556 name = QString(
"%1 / %2" ).arg( mLayer->datasetGroupMetadata( indexScalar ).name(), mLayer->datasetGroupMetadata( indexVector ).name() );
557 else if ( indexScalar > -1 )
558 name = mLayer->datasetGroupMetadata( indexScalar ).name();
559 else if ( indexVector > -1 )
560 name = mLayer->datasetGroupMetadata( indexVector ).name();
567 if ( indexScalar > -1 )
569 const QString scalarNameKey = u
"scalarName"_s;
571 QIcon(),
nullptr, scalarNameKey );
599 for (
const QPair< QString, QColor > &item : items )
602 u
"scalarLegend"_s + QUuid::createUuid().toString(),
611 if ( indexVector > -1 )
614 const QString vectorNameKey = u
"vectorName"_s;
619 const QColor arrowColor = settings.
color();
622 vectorIcon,
nullptr, vectorNameKey );
629 vectorIcon,
nullptr, vectorNameKey );
656 for (
const QPair< QString, QColor > &item : items )
659 u
"vectorLegend"_s + QUuid::createUuid().toString(),
688 return QList<QgsLayerTreeModelLegendNode *>();
QFlags< MapLayerLegendFlag > MapLayerLegendFlags
Map layer legend flags.
@ Exact
Assigns the color of the exact matching value in the color ramp item list.
@ Linear
Interpolates the color between two class breaks linearly.
@ Discrete
Assigns the color of the higher class for every pixel between two class breaks.
@ ExcludeByDefault
If set, the layer should not be included in legends by default, and must be manually added by a user.
Abstract base class - its implementations define different approaches to the labeling of a vector lay...
virtual QStringList subProviders() const
Gets list of sub-providers within the layer's labeling.
virtual QgsPalLayerSettings settings(const QString &providerId=QString()) const =0
Gets associated label settings.
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
static QgsImageCache * imageCache()
Returns the application's image cache, used for caching resampled versions of raster images.
Settings for a color ramp legend node.
bool useContinuousLegend() const
Returns true if a continuous gradient legend will be used.
void readXml(const QDomElement &element, const QgsReadWriteContext &context)
Reads settings from an XML element.
void writeXml(QDomDocument &doc, QDomElement &element, const QgsReadWriteContext &context) const
Writes settings to an XML element.
A legend node which renders a color ramp.
A ramp shader will color a raster pixel based on a list of values ranges in a ramp.
void legendSymbologyItems(QList< QPair< QString, QColor > > &symbolItems) const override
Returns legend symbology items if provided by renderer.
Qgis::ShaderInterpolationMethod colorRampType() const
Returns the color ramp interpolation method.
const QgsColorRampLegendNodeSettings * legendSettings() const
Returns the color ramp shader legend settings.
QList< QgsColorRampShader::ColorRampItem > colorRampItemList() const
Returns the custom color map.
QgsColorRamp * createColorRamp() const
Creates a gradient color ramp from shader settings.
Default legend implementation for mesh layers.
QgsDefaultMeshLayerLegend(QgsMeshLayer *ml)
Creates an instance for the given mesh layer.
QList< QgsLayerTreeModelLegendNode * > createLayerTreeModelLegendNodes(QgsLayerTreeLayer *nodeLayer) override
Returns list of legend nodes to be used for a particular layer tree layer node.
Default legend implementation for point cloud layers.
QList< QgsLayerTreeModelLegendNode * > createLayerTreeModelLegendNodes(QgsLayerTreeLayer *nodeLayer) override
Returns list of legend nodes to be used for a particular layer tree layer node.
QgsDefaultPointCloudLayerLegend(QgsPointCloudLayer *layer)
Creates an instance for the given point cloud layer.
Default legend implementation for raster layers.
QgsDefaultRasterLayerLegend(QgsRasterLayer *rl)
QList< QgsLayerTreeModelLegendNode * > createLayerTreeModelLegendNodes(QgsLayerTreeLayer *nodeLayer) override
Returns list of legend nodes to be used for a particular layer tree layer node.
Default legend implementation for vector layers.
QList< QgsLayerTreeModelLegendNode * > createLayerTreeModelLegendNodes(QgsLayerTreeLayer *nodeLayer) override
Returns list of legend nodes to be used for a particular layer tree layer node.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const override
Writes configuration to a DOM element, to be used later with readXml().
void readXml(const QDomElement &elem, const QgsReadWriteContext &context) override
Reads configuration from a DOM element previously written by writeXml().
QgsDefaultVectorLayerLegend(QgsVectorLayer *vl)
Abstract base class for all 2D vector feature renderers.
virtual QList< QgsLayerTreeModelLegendNode * > createLegendNodes(QgsLayerTreeLayer *nodeLayer) const
Returns a list of legend nodes to be used for the legend for the renderer.
virtual QString legendClassificationAttribute() const
If supported by the renderer, return classification attribute for the use in legend.
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.
Implementation of legend node interface for displaying arbitrary raster images.
@ ColorRamp
Render with a color ramp.
@ SingleColor
Render with a single color.
Layer tree node points to a map layer.
QString name() const override
Returns the layer's name.
QgsMapLayer * layer() const
Returns the map layer associated with this node.
An abstract interface for legend items returned from QgsMapLayerLegend implementation.
virtual QVariant data(int role) const =0
Returns data associated with the item. Must be implemented in derived class.
@ RuleKey
Rule key of the node (QString).
virtual void setColumnBreak(bool breakBeforeNode)
Sets whether a forced column break should occur before the node.
virtual void setUserPatchSize(QSizeF size)
Sets the user (overridden) size for the legend node.
virtual void setUserLabel(const QString &userLabel)
void setCustomProperty(const QString &key, const QVariant &value)
Sets a custom property for the node. Properties are stored in a map and saved in project file.
void removeCustomProperty(const QString &key)
Remove a custom property from layer. Properties are stored in a map and saved in project file.
QVariant customProperty(const QString &key, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer. Properties are stored in a map and saved in project file.
QStringList customProperties() const
Returns list of keys stored in custom properties.
Represents a patch shape for use in map legends.
void readXml(const QDomElement &element, const QgsReadWriteContext &context)
Read settings from a DOM element.
void writeXml(QDomElement &element, QDomDocument &doc, const QgsReadWriteContext &context) const
Write settings into a DOM element.
static void setLegendNodeOrder(QgsLayerTreeLayer *nodeLayer, const QList< int > &order)
static std::unique_ptr< QgsSymbol > legendNodeCustomSymbol(QgsLayerTreeLayer *nodeLayer, int originalIndex)
Returns the custom legend symbol for the legend node belonging to nodeLayer at the specified original...
static void setLegendNodeColorRampSettings(QgsLayerTreeLayer *nodeLayer, int originalIndex, const QgsColorRampLegendNodeSettings *settings)
Sets a custom legend color ramp settings for the legend node belonging to nodeLayer at the specified ...
static void setLegendNodeCustomSymbol(QgsLayerTreeLayer *nodeLayer, int originalIndex, const QgsSymbol *symbol)
Sets a custom legend symbol for the legend node belonging to nodeLayer at the specified originalIndex...
static QString legendNodeUserLabel(QgsLayerTreeLayer *nodeLayer, int originalIndex)
static QSizeF legendNodeSymbolSize(QgsLayerTreeLayer *nodeLayer, int originalIndex)
Returns the legend node symbol size for the legend node belonging to nodeLayer at the specified origi...
static bool hasLegendNodeUserLabel(QgsLayerTreeLayer *nodeLayer, int originalIndex)
static bool legendNodeColumnBreak(QgsLayerTreeLayer *nodeLayer, int originalIndex)
Returns whether a forced column break should occur before the node.
static bool hasLegendNodeOrder(QgsLayerTreeLayer *nodeLayer)
static void setLegendNodeUserLabel(QgsLayerTreeLayer *nodeLayer, int originalIndex, const QString &newLabel)
static void setLegendNodeSymbolSize(QgsLayerTreeLayer *nodeLayer, int originalIndex, QSizeF size)
Sets the legend symbol size for the legend node belonging to nodeLayer at the specified originalIndex...
static QgsColorRampLegendNodeSettings * legendNodeColorRampSettings(QgsLayerTreeLayer *nodeLayer, int originalIndex)
Returns the custom legend color ramp settings for the legend node belonging to nodeLayer at the speci...
static void setLegendNodeColumnBreak(QgsLayerTreeLayer *nodeLayer, int originalIndex, bool columnBreakBeforeNode)
Sets whether a forced column break should occur before the node.
static void setLegendNodePatchShape(QgsLayerTreeLayer *nodeLayer, int originalIndex, const QgsLegendPatchShape &shape)
Sets the legend patch shape for the legend node belonging to nodeLayer at the specified originalIndex...
static QList< int > legendNodeOrder(QgsLayerTreeLayer *nodeLayer)
static void applyLayerNodeProperties(QgsLayerTreeLayer *nodeLayer, QList< QgsLayerTreeModelLegendNode * > &nodes)
update according to layer node's custom properties (order of items, user labels for items)
static QgsLegendPatchShape legendNodePatchShape(QgsLayerTreeLayer *nodeLayer, int originalIndex)
Returns the legend patch shape for the legend node belonging to nodeLayer at the specified originalIn...
virtual void readXml(const QDomElement &elem, const QgsReadWriteContext &context)
Reads configuration from a DOM element previously written by writeXml().
static QgsMapLayerLegend * defaultMeshLegend(QgsMeshLayer *ml)
Create new legend implementation for mesh layer.
static QgsMapLayerLegend * defaultPointCloudLegend(QgsPointCloudLayer *layer)
Create new legend implementation for a point cloud layer.
QgsMapLayerLegend(QObject *parent=nullptr)
Constructor for QgsMapLayerLegend.
virtual QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Writes configuration to a DOM element, to be used later with readXml().
static QgsMapLayerLegend * defaultRasterLegend(QgsRasterLayer *rl)
Create new legend implementation for raster layer.
static QgsMapLayerLegend * defaultVectorLegend(QgsVectorLayer *vl)
Create new legend implementation for vector layer.
virtual QList< QgsLayerTreeModelLegendNode * > createLayerTreeModelLegendNodes(QgsLayerTreeLayer *nodeLayer)=0
Returns list of legend nodes to be used for a particular layer tree layer node.
void itemsChanged()
Emitted when existing items/nodes got invalid and should be replaced by new ones.
QgsMapLayerLegend * legend() const
Can be nullptr.
void rendererChanged()
Signal emitted when renderer is changed.
void nameChanged()
Emitted when the name has been changed.
Represents a mesh layer supporting display of data on structured or unstructured meshes.
Represents a mesh renderer settings for scalar datasets.
QgsColorRampShader colorRampShader() const
Returns color ramp shader function.
Represents all mesh renderer settings.
QgsMeshRendererScalarSettings scalarSettings(int groupIndex) const
Returns renderer settings.
int activeVectorDatasetGroup() const
Returns the active vector dataset group.
int activeScalarDatasetGroup() const
Returns the active scalar dataset group.
QgsMeshRendererVectorSettings vectorSettings(int groupIndex) const
Returns renderer settings.
Represents a renderer settings for vector datasets.
QColor color() const
Returns color used for drawing arrows.
QgsColorRampShader colorRampShader() const
Sets the color ramp shader used to render vector datasets.
QgsInterpolatedLineColor::ColoringMethod coloringMethod() const
Returns the coloring method used to render vector datasets.
Contains settings for how a map layer will be labeled.
Represents a map layer supporting display of point clouds.
Abstract base class for 2d point cloud renderers.
virtual QList< QgsLayerTreeModelLegendNode * > createLegendNodes(QgsLayerTreeLayer *nodeLayer)
Creates a set of legend nodes representing the renderer.
static QgsProject * instance()
Returns the QgsProject singleton instance.
Represents a raster layer.
double maximumValue() const
Returns the minimum value for the raster shader.
double minimumValue() const
Returns the maximum value for the raster shader.
Implementation of legend node interface for displaying raster legend entries.
A container for the context for various read/write operations on objects.
void setPathResolver(const QgsPathResolver &resolver)
Sets up path resolver for conversion between relative and absolute paths.
A child rule for QgsRuleBasedLabeling.
const QgsRuleBasedLabeling::Rule * findRuleByKey(const QString &key) const
Try to find a rule given its unique key.
QString description() const
A human readable description for this rule.
Rule based labeling for a vector layer.
QgsRuleBasedLabeling::Rule * rootRule()
Stores settings for use within QGIS.
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
Implementation of legend node interface for displaying arbitrary labels with icons.
static std::unique_ptr< QgsSymbol > loadSymbol(const QDomElement &element, const QgsReadWriteContext &context)
Attempts to load a symbol from a DOM element.
static QString encodeSize(QSizeF size)
Encodes a QSizeF to a string.
static QDomElement saveSymbol(const QString &symbolName, const QgsSymbol *symbol, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a symbol definition to XML.
static QSizeF decodeSize(const QString &string)
Decodes a QSizeF from a string.
Implementation of legend node interface for displaying preview of vector symbols and their labels and...
Abstract base class for all rendered symbols.
Container for all settings relating to text rendering.
A legend node for a labeling text symbol.
Represents a vector layer which manages a vector based dataset.
Implementation of legend node interface for displaying WMS legend entries.
#define QgsDebugError(str)
QList< QPair< QString, QColor > > QgsLegendColorList