QGIS API Documentation  3.20.0-Odense (decaadbb31)
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  return symbolRenderer.release();
129  }
130  else
131  {
132  return nullptr;
133  }
134 }
135 
136 QDomElement QgsEmbeddedSymbolRenderer::save( QDomDocument &doc, const QgsReadWriteContext &context )
137 {
138  QDomElement rendererElem = doc.createElement( RENDERER_TAG_NAME );
139  rendererElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "embeddedSymbol" ) );
140  rendererElem.setAttribute( QStringLiteral( "symbollevels" ), ( mUsingSymbolLevels ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );
141  rendererElem.setAttribute( QStringLiteral( "forceraster" ), ( mForceRaster ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );
142 
144  symbols[QStringLiteral( "0" )] = mDefaultSymbol.get();
145  QDomElement symbolsElem = QgsSymbolLayerUtils::saveSymbols( symbols, QStringLiteral( "symbols" ), doc, context );
146  rendererElem.appendChild( symbolsElem );
147 
149  mPaintEffect->saveProperties( doc, rendererElem );
150 
151  if ( !mOrderBy.isEmpty() )
152  {
153  QDomElement orderBy = doc.createElement( QStringLiteral( "orderby" ) );
154  mOrderBy.save( orderBy );
155  rendererElem.appendChild( orderBy );
156  }
157  rendererElem.setAttribute( QStringLiteral( "enableorderby" ), ( mOrderByEnabled ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );
158 
159  return rendererElem;
160 }
161 
163 {
164  Q_UNUSED( context )
165  QgsSymbolList lst;
166  lst.append( mDefaultSymbol.get() );
167  return lst;
168 }
169 
171 {
172  return mDefaultSymbol.get();
173 }
174 
176 {
177  Q_ASSERT( symbol );
178  mDefaultSymbol.reset( symbol );
179 }
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
store renderer info to 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.
QgsPaintEffect * mPaintEffect
Definition: qgsrenderer.h:537
QString type() const
Definition: qgsrenderer.h:141
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:262
QgsFeatureRequest::OrderBy mOrderBy
Definition: qgsrenderer.h:553
virtual void startRender(QgsRenderContext &context, const QgsFields &fields)
Must be called when a new render cycle is started.
Definition: qgsrenderer.cpp:94
QgsFeatureRequest::OrderBy orderBy() const
Gets the order in which features shall be processed by this renderer.
void CORE_EXPORT save(QDomElement &elem) const
Serialize to XML.
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
static bool isDefaultStack(QgsPaintEffect *effect)
Tests whether a paint effect matches the default effects stack.
virtual bool saveProperties(QDomDocument &doc, QDomElement &element) const
Saves the current state of the effect to a DOM element.
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:49
QMap< QString, QgsSymbol * > QgsSymbolMap
Definition: qgsrenderer.h:44
QList< QgsSymbol * > QgsSymbolList
Definition: qgsrenderer.h:43