QGIS API Documentation  3.21.0-Master (5b68dc587e)
qgsembeddedsymbolrenderer.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsembeddedsymbolrenderer.cpp
3  ---------------------
4  begin : March 2021
5  copyright : (C) 2021 by Nyall Dawson
6  email : nyall dot dawson at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
17 #include "qgspainteffectregistry.h"
18 #include "qgssymbollayerutils.h"
20 #include "qgssymbol.h"
21 #include "qgspainteffect.h"
22 
24  : QgsFeatureRenderer( QStringLiteral( "embeddedSymbol" ) )
25  , mDefaultSymbol( defaultSymbol )
26 {
27  Q_ASSERT( mDefaultSymbol );
28 }
29 
31 
33 {
34  if ( feature.embeddedSymbol() )
35  return const_cast< QgsSymbol * >( feature.embeddedSymbol() );
36  else
37  return mDefaultSymbol.get();
38 }
39 
41 {
42  Q_UNUSED( context )
43  if ( feature.embeddedSymbol() )
44  return const_cast< QgsSymbol * >( feature.embeddedSymbol() );
45  else
46  return mDefaultSymbol.get();
47 }
48 
50 {
51  QgsFeatureRenderer::startRender( context, fields );
52 
53  mDefaultSymbol->startRender( context, fields );
54 }
55 
56 bool QgsEmbeddedSymbolRenderer::renderFeature( const QgsFeature &feature, QgsRenderContext &context, int layer, bool selected, bool drawVertexMarker )
57 {
58  if ( const QgsSymbol *symbol = feature.embeddedSymbol() )
59  {
60  std::unique_ptr< QgsSymbol > clone( symbol->clone() );
61 
62  clone->startRender( context );
63  renderFeatureWithSymbol( feature, clone.get(), context, layer, selected, drawVertexMarker );
64  clone->stopRender( context );
65  }
66  else
67  {
68  renderFeatureWithSymbol( feature, mDefaultSymbol.get(), context, layer, selected, drawVertexMarker );
69  }
70  return true;
71 }
72 
74 {
76  mDefaultSymbol->stopRender( context );
77 }
78 
79 QSet<QString> QgsEmbeddedSymbolRenderer::usedAttributes( const QgsRenderContext &context ) const
80 {
81  QSet<QString> attributes;
82  if ( mDefaultSymbol )
83  attributes.unite( mDefaultSymbol->usedAttributes( context ) );
84  return attributes;
85 }
86 
88 {
89  return true;
90 }
91 
93 {
94  QgsEmbeddedSymbolRenderer *r = new QgsEmbeddedSymbolRenderer( mDefaultSymbol->clone() );
95  copyRendererData( r );
96  return r;
97 }
98 
99 QgsFeatureRenderer::Capabilities QgsEmbeddedSymbolRenderer::capabilities()
100 {
101  return SymbolLevels;
102 }
103 
105 {
106  QDomElement symbolsElem = element.firstChildElement( QStringLiteral( "symbols" ) );
107  if ( symbolsElem.isNull() )
108  return nullptr;
109 
110  QgsSymbolMap symbolMap = QgsSymbolLayerUtils::loadSymbols( symbolsElem, context );
111 
112  if ( !symbolMap.contains( QStringLiteral( "0" ) ) )
113  return nullptr;
114 
115  QgsEmbeddedSymbolRenderer *r = new QgsEmbeddedSymbolRenderer( symbolMap.take( QStringLiteral( "0" ) ) );
116  return r;
117 }
118 
120 {
121  if ( renderer->type() == QLatin1String( "embeddedSymbol" ) )
122  {
123  return dynamic_cast<QgsEmbeddedSymbolRenderer *>( renderer->clone() );
124  }
125  else if ( renderer->type() == QLatin1String( "singleSymbol" ) )
126  {
127  std::unique_ptr< QgsEmbeddedSymbolRenderer > symbolRenderer = std::make_unique< QgsEmbeddedSymbolRenderer >( static_cast< const QgsSingleSymbolRenderer * >( renderer )->symbol()->clone() );
128  renderer->copyRendererData( symbolRenderer.get() );
129  return symbolRenderer.release();
130  }
131  else
132  {
133  return nullptr;
134  }
135 }
136 
137 QDomElement QgsEmbeddedSymbolRenderer::save( QDomDocument &doc, const QgsReadWriteContext &context )
138 {
139  QDomElement rendererElem = doc.createElement( RENDERER_TAG_NAME );
140  rendererElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "embeddedSymbol" ) );
141 
143  symbols[QStringLiteral( "0" )] = mDefaultSymbol.get();
144  const QDomElement symbolsElem = QgsSymbolLayerUtils::saveSymbols( symbols, QStringLiteral( "symbols" ), doc, context );
145  rendererElem.appendChild( symbolsElem );
146 
147  saveRendererData( doc, rendererElem, context );
148 
149  return rendererElem;
150 }
151 
153 {
154  Q_UNUSED( context )
155  QgsSymbolList lst;
156  lst.append( mDefaultSymbol.get() );
157  return lst;
158 }
159 
161 {
162  return mDefaultSymbol.get();
163 }
164 
166 {
167  Q_ASSERT( symbol );
168  mDefaultSymbol.reset( symbol );
169 }
A vector feature renderer which uses embedded feature symbology to render per-feature symbols.
bool usesEmbeddedSymbols() const override
Returns true if the renderer uses embedded symbols for features.
QgsSymbol * defaultSymbol() const
Returns the default symbol which will be rendered for any feature which does not have embedded symbol...
QgsEmbeddedSymbolRenderer * clone() const override
Create a deep copy of this renderer.
QgsSymbolList symbols(QgsRenderContext &context) const override
Returns list of symbols used by the renderer.
QgsEmbeddedSymbolRenderer(QgsSymbol *defaultSymbol)
Constructor for QgsEmbeddedSymbolRenderer.
static QgsEmbeddedSymbolRenderer * convertFromRenderer(const QgsFeatureRenderer *renderer)
Creates a QgsEmbeddedSymbolRenderer from an existing renderer.
QgsSymbol * symbolForFeature(const QgsFeature &feature, QgsRenderContext &context) const override
To be overridden.
QgsSymbol * originalSymbolForFeature(const QgsFeature &feature, QgsRenderContext &context) const override
Returns symbol for feature.
bool renderFeature(const QgsFeature &feature, QgsRenderContext &context, int layer=-1, bool selected=false, bool drawVertexMarker=false) SIP_THROW(QgsCsException) override
Render a feature using this renderer in the given context.
void setDefaultSymbol(QgsSymbol *symbol)
Sets the default symbol which will be rendered for any feature which does not have embedded symbology...
void stopRender(QgsRenderContext &context) override
Must be called when a render cycle has finished, to allow the renderer to clean up.
QgsFeatureRenderer::Capabilities capabilities() override
Returns details about internals of this renderer.
static QgsFeatureRenderer * create(QDomElement &element, const QgsReadWriteContext &context)
Creates a new embedded symbol renderer from an XML element, using the supplied read/write context.
void startRender(QgsRenderContext &context, const QgsFields &fields) override
Must be called when a new render cycle is started.
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns a list of attributes required by this renderer.
~QgsEmbeddedSymbolRenderer() override
QDomElement save(QDomDocument &doc, const QgsReadWriteContext &context) override
Stores renderer properties to an XML element.
virtual QgsFeatureRenderer * clone() const =0
Create a deep copy of this renderer.
void renderFeatureWithSymbol(const QgsFeature &feature, QgsSymbol *symbol, QgsRenderContext &context, int layer, bool selected, bool drawVertexMarker) SIP_THROW(QgsCsException)
Render the feature with the symbol using context.
virtual void stopRender(QgsRenderContext &context)
Must be called when a render cycle has finished, to allow the renderer to clean up.
QString type() const
Definition: qgsrenderer.h:142
void copyRendererData(QgsFeatureRenderer *destRenderer) const
Clones generic renderer data to another renderer.
Definition: qgsrenderer.cpp:52
@ SymbolLevels
Rendering with symbol levels (i.e. implements symbols(), symbolForFeature())
Definition: qgsrenderer.h:263
void saveRendererData(QDomDocument &doc, QDomElement &element, const QgsReadWriteContext &context)
Saves generic renderer data into the specified element.
virtual void startRender(QgsRenderContext &context, const QgsFields &fields)
Must be called when a new render cycle is started.
Definition: qgsrenderer.cpp:96
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:56
const QgsSymbol * embeddedSymbol() const
Returns the feature's embedded symbology, or nullptr if the feature has no embedded symbol.
Definition: qgsfeature.cpp:288
Container of fields for a vector layer.
Definition: qgsfields.h:45
The class is used as a container of context for various read/write operations on other objects.
Contains information about the context of a rendering operation.
static QgsSymbolMap loadSymbols(QDomElement &element, const QgsReadWriteContext &context)
Reads a collection of symbols from XML and returns them in a map. Caller is responsible for deleting ...
static QDomElement saveSymbols(QgsSymbolMap &symbols, const QString &tagName, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a collection of symbols to XML with specified tagName for the top-level element.
Abstract base class for all rendered symbols.
Definition: qgssymbol.h:38
#define RENDERER_TAG_NAME
Definition: qgsrenderer.h:50
QMap< QString, QgsSymbol * > QgsSymbolMap
Definition: qgsrenderer.h:45
QList< QgsSymbol * > QgsSymbolList
Definition: qgsrenderer.h:44