QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
qgspointclusterrenderer.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgspointclusterrenderer.cpp
3  ---------------------------
4  begin : February 2016
5  copyright : (C) 2016 by Nyall Dawson
6  email : nyall dot dawson at gmail dot com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
20 #include "qgssymbollayerutils.h"
21 #include "qgspainteffectregistry.h"
22 #include "qgspainteffect.h"
23 #include "qgsmarkersymbollayer.h"
24 #include "qgsproperty.h"
25 #include "qgsstyleentityvisitor.h"
26 #include "qgsmarkersymbol.h"
27 
28 #include <cmath>
29 
31  : QgsPointDistanceRenderer( QStringLiteral( "pointCluster" ) )
32 {
33  mClusterSymbol.reset( new QgsMarkerSymbol() );
34  mClusterSymbol->setSize( 4 );
35  mClusterSymbol->setColor( QColor( 245, 75, 80 ) );
36 
38  fm->setFontFamily( QFont().defaultFamily() );
39  fm->setColor( QColor( 255, 255, 255 ) );
40  fm->setSize( 3.2 );
41  fm->setOffset( QPointF( 0, -0.4 ) );
43  mClusterSymbol->insertSymbolLayer( 1, fm );
44 }
45 
47 {
49  if ( mRenderer )
50  r->setEmbeddedRenderer( mRenderer->clone() );
57  if ( mClusterSymbol )
58  {
59  r->setClusterSymbol( mClusterSymbol->clone() );
60  }
61  copyRendererData( r );
62  return r;
63 }
64 
65 void QgsPointClusterRenderer::drawGroup( QPointF centerPoint, QgsRenderContext &context, const ClusteredGroup &group ) const
66 {
67  if ( group.size() > 1 )
68  {
69  mClusterSymbol->renderPoint( centerPoint, &( group.at( 0 ).feature ), context, -1, false );
70  }
71  else
72  {
73  //single isolated symbol, draw it untouched
74  QgsMarkerSymbol *symbol = group.at( 0 ).symbol();
75  symbol->startRender( context );
76  symbol->renderPoint( centerPoint, &( group.at( 0 ).feature ), context, -1, group.at( 0 ).isSelected );
77  symbol->stopRender( context );
78  }
79 }
80 
82 {
83  if ( mClusterSymbol )
84  {
85  mClusterSymbol->startRender( context, fields );
86  }
87  QgsPointDistanceRenderer::startRender( context, fields );
88 }
89 
91 {
93  if ( mClusterSymbol )
94  {
95  mClusterSymbol->stopRender( context );
96  }
97 }
98 
99 QgsFeatureRenderer *QgsPointClusterRenderer::create( QDomElement &symbologyElem, const QgsReadWriteContext &context )
100 {
102  r->setTolerance( symbologyElem.attribute( QStringLiteral( "tolerance" ), QStringLiteral( "0.00001" ) ).toDouble() );
103  r->setToleranceUnit( QgsUnitTypes::decodeRenderUnit( symbologyElem.attribute( QStringLiteral( "toleranceUnit" ), QStringLiteral( "MapUnit" ) ) ) );
104  r->setToleranceMapUnitScale( QgsSymbolLayerUtils::decodeMapUnitScale( symbologyElem.attribute( QStringLiteral( "toleranceUnitScale" ) ) ) );
105 
106  //look for an embedded renderer <renderer-v2>
107  QDomElement embeddedRendererElem = symbologyElem.firstChildElement( QStringLiteral( "renderer-v2" ) );
108  if ( !embeddedRendererElem.isNull() )
109  {
110  r->setEmbeddedRenderer( QgsFeatureRenderer::load( embeddedRendererElem, context ) );
111  }
112 
113  //center symbol
114  const QDomElement centerSymbolElem = symbologyElem.firstChildElement( QStringLiteral( "symbol" ) );
115  if ( !centerSymbolElem.isNull() )
116  {
117  r->setClusterSymbol( QgsSymbolLayerUtils::loadSymbol<QgsMarkerSymbol>( centerSymbolElem, context ) );
118  }
119  return r;
120 }
121 
123 {
124  return mClusterSymbol.get();
125 }
126 
127 QDomElement QgsPointClusterRenderer::save( QDomDocument &doc, const QgsReadWriteContext &context )
128 {
129  QDomElement rendererElement = doc.createElement( RENDERER_TAG_NAME );
130  rendererElement.setAttribute( QStringLiteral( "type" ), QStringLiteral( "pointCluster" ) );
131  rendererElement.setAttribute( QStringLiteral( "tolerance" ), QString::number( mTolerance ) );
132  rendererElement.setAttribute( QStringLiteral( "toleranceUnit" ), QgsUnitTypes::encodeUnit( mToleranceUnit ) );
133  rendererElement.setAttribute( QStringLiteral( "toleranceUnitScale" ), QgsSymbolLayerUtils::encodeMapUnitScale( mToleranceMapUnitScale ) );
134 
135  if ( mRenderer )
136  {
137  const QDomElement embeddedRendererElem = mRenderer->save( doc, context );
138  rendererElement.appendChild( embeddedRendererElem );
139  }
140  if ( mClusterSymbol )
141  {
142  const QDomElement centerSymbolElem = QgsSymbolLayerUtils::saveSymbol( QStringLiteral( "centerSymbol" ), mClusterSymbol.get(), doc, context );
143  rendererElement.appendChild( centerSymbolElem );
144  }
145 
146  saveRendererData( doc, rendererElement, context );
147 
148  return rendererElement;
149 }
150 
151 QSet<QString> QgsPointClusterRenderer::usedAttributes( const QgsRenderContext &context ) const
152 {
153  QSet<QString> attr = QgsPointDistanceRenderer::usedAttributes( context );
154  if ( mClusterSymbol )
155  attr.unite( mClusterSymbol->usedAttributes( context ) );
156  return attr;
157 }
158 
160 {
161  if ( !QgsPointDistanceRenderer::accept( visitor ) )
162  return false;
163 
164  if ( mClusterSymbol )
165  {
166  QgsStyleSymbolEntity entity( mClusterSymbol.get() );
167  if ( !visitor->visit( QgsStyleEntityVisitorInterface::StyleLeaf( &entity, QStringLiteral( "cluster" ), QObject::tr( "Cluster Symbol" ) ) ) )
168  return false;
169  }
170 
171  return true;
172 }
173 
175 {
176  mClusterSymbol.reset( symbol );
177 }
178 
180 {
181  if ( renderer->type() == QLatin1String( "pointCluster" ) )
182  {
183  return dynamic_cast<QgsPointClusterRenderer *>( renderer->clone() );
184  }
185  else if ( renderer->type() == QLatin1String( "singleSymbol" ) ||
186  renderer->type() == QLatin1String( "categorizedSymbol" ) ||
187  renderer->type() == QLatin1String( "graduatedSymbol" ) ||
188  renderer->type() == QLatin1String( "RuleRenderer" ) )
189  {
190  QgsPointClusterRenderer *pointRenderer = new QgsPointClusterRenderer();
191  pointRenderer->setEmbeddedRenderer( renderer->clone() );
192  renderer->copyRendererData( pointRenderer );
193  return pointRenderer;
194  }
195  else if ( renderer->type() == QLatin1String( "pointDisplacement" ) )
196  {
197  QgsPointClusterRenderer *pointRenderer = new QgsPointClusterRenderer();
198  const QgsPointDisplacementRenderer *displacementRenderer = static_cast< const QgsPointDisplacementRenderer * >( renderer );
199  if ( displacementRenderer->embeddedRenderer() )
200  pointRenderer->setEmbeddedRenderer( displacementRenderer->embeddedRenderer()->clone() );
201  pointRenderer->setTolerance( displacementRenderer->tolerance() );
202  pointRenderer->setToleranceUnit( displacementRenderer->toleranceUnit() );
203  pointRenderer->setToleranceMapUnitScale( displacementRenderer->toleranceMapUnitScale() );
204  if ( const_cast< QgsPointDisplacementRenderer * >( displacementRenderer )->centerSymbol() )
205  pointRenderer->setClusterSymbol( const_cast< QgsPointDisplacementRenderer * >( displacementRenderer )->centerSymbol()->clone() );
206  renderer->copyRendererData( pointRenderer );
207  return pointRenderer;
208  }
209  else
210  {
211  return nullptr;
212  }
213 }
QgsFeatureRenderer::copyRendererData
void copyRendererData(QgsFeatureRenderer *destRenderer) const
Clones generic renderer data to another renderer.
Definition: qgsrenderer.cpp:52
QgsSymbolLayer::setColor
virtual void setColor(const QColor &color)
Sets the "representative" color for the symbol layer.
Definition: qgssymbollayer.cpp:252
QgsPointDistanceRenderer::mToleranceUnit
QgsUnitTypes::RenderUnit mToleranceUnit
Unit for distance tolerance.
Definition: qgspointdistancerenderer.h:245
QgsReadWriteContext
The class is used as a container of context for various read/write operations on other objects.
Definition: qgsreadwritecontext.h:34
QgsSymbolLayerUtils::encodeMapUnitScale
static QString encodeMapUnitScale(const QgsMapUnitScale &mapUnitScale)
Definition: qgssymbollayerutils.cpp:666
QgsStyleSymbolEntity
A symbol entity for QgsStyle databases.
Definition: qgsstyle.h:1341
qgssymbollayerutils.h
QgsFields
Container of fields for a vector layer.
Definition: qgsfields.h:44
QgsFeatureRenderer::type
QString type() const
Definition: qgsrenderer.h:142
qgsmarkersymbollayer.h
QgsRenderContext
Contains information about the context of a rendering operation.
Definition: qgsrendercontext.h:59
QgsPointClusterRenderer::convertFromRenderer
static QgsPointClusterRenderer * convertFromRenderer(const QgsFeatureRenderer *renderer)
Creates a QgsPointClusterRenderer from an existing renderer.
Definition: qgspointclusterrenderer.cpp:179
QgsStyleEntityVisitorInterface
An interface for classes which can visit style entity (e.g. symbol) nodes (using the visitor pattern)...
Definition: qgsstyleentityvisitor.h:33
QgsPointClusterRenderer::create
static QgsFeatureRenderer * create(QDomElement &symbologyElem, const QgsReadWriteContext &context)
Creates a renderer from XML element.
Definition: qgspointclusterrenderer.cpp:99
qgspainteffectregistry.h
QgsPointDistanceRenderer::embeddedRenderer
const QgsFeatureRenderer * embeddedRenderer() const override
Returns the current embedded renderer (subrenderer) for this feature renderer.
Definition: qgspointdistancerenderer.cpp:173
QgsProperty::fromExpression
static QgsProperty fromExpression(const QString &expression, bool isActive=true)
Returns a new ExpressionBasedProperty created from the specified expression.
Definition: qgsproperty.cpp:237
qgspainteffect.h
QgsPointDistanceRenderer::mLabelFont
QFont mLabelFont
Label font.
Definition: qgspointdistancerenderer.h:250
QgsFeatureRenderer::load
static QgsFeatureRenderer * load(QDomElement &symbologyElem, const QgsReadWriteContext &context)
create a renderer from XML element
Definition: qgsrenderer.cpp:157
QgsPointClusterRenderer::save
QDomElement save(QDomDocument &doc, const QgsReadWriteContext &context) override
Stores renderer properties to an XML element.
Definition: qgspointclusterrenderer.cpp:127
QgsPointDistanceRenderer::toleranceMapUnitScale
const QgsMapUnitScale & toleranceMapUnitScale() const
Returns the map unit scale object for the distance tolerance.
Definition: qgspointdistancerenderer.h:229
QgsPointClusterRenderer::clone
QgsPointClusterRenderer * clone() const override
Create a deep copy of this renderer.
Definition: qgspointclusterrenderer.cpp:46
QgsStyleEntityVisitorInterface::StyleLeaf
Contains information relating to the style entity currently being visited.
Definition: qgsstyleentityvisitor.h:60
QgsPointClusterRenderer::startRender
void startRender(QgsRenderContext &context, const QgsFields &fields) override
Must be called when a new render cycle is started.
Definition: qgspointclusterrenderer.cpp:81
QgsPointDistanceRenderer::mMinLabelScale
double mMinLabelScale
Maximum scale denominator for label display. A zero value indicates no scale limitation.
Definition: qgspointdistancerenderer.h:256
QgsPointClusterRenderer::clusterSymbol
QgsMarkerSymbol * clusterSymbol()
Returns the symbol used for rendering clustered groups (but not ownership of the symbol).
Definition: qgspointclusterrenderer.cpp:122
QgsMarkerSymbol::clone
QgsMarkerSymbol * clone() const override
Returns a deep copy of this symbol.
Definition: qgsmarkersymbol.cpp:523
QgsUnitTypes::decodeRenderUnit
static Q_INVOKABLE QgsUnitTypes::RenderUnit decodeRenderUnit(const QString &string, bool *ok=nullptr)
Decodes a render unit from a string.
Definition: qgsunittypes.cpp:2948
QgsPointDistanceRenderer::mRenderer
std::unique_ptr< QgsFeatureRenderer > mRenderer
Embedded base renderer. This can be used for rendering individual, isolated points.
Definition: qgspointdistancerenderer.h:234
QgsPointClusterRenderer
A renderer that automatically clusters points with the same geographic position.
Definition: qgspointclusterrenderer.h:31
QgsPointDistanceRenderer::toleranceUnit
QgsUnitTypes::RenderUnit toleranceUnit() const
Returns the units for the tolerance distance.
Definition: qgspointdistancerenderer.h:212
QgsPointClusterRenderer::usedAttributes
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns a list of attributes required by this renderer.
Definition: qgspointclusterrenderer.cpp:151
QgsPointDisplacementRenderer::centerSymbol
QgsMarkerSymbol * centerSymbol()
Returns the symbol for the center of a displacement group (but not ownership of the symbol).
Definition: qgspointdisplacementrenderer.cpp:189
QgsSymbolLayer::PropertyCharacter
@ PropertyCharacter
Character, eg for font marker symbol layers.
Definition: qgssymbollayer.h:152
QgsPointDistanceRenderer::setLabelColor
void setLabelColor(const QColor &color)
Sets the color to use for for labeling points.
Definition: qgspointdistancerenderer.h:170
QgsUnitTypes::encodeUnit
static Q_INVOKABLE QString encodeUnit(QgsUnitTypes::DistanceUnit unit)
Encodes a distance unit to a string.
Definition: qgsunittypes.cpp:122
QgsSymbol::stopRender
void stopRender(QgsRenderContext &context)
Ends the rendering process.
Definition: qgssymbol.cpp:842
QgsMarkerSymbol
A marker symbol type, for rendering Point and MultiPoint geometries.
Definition: qgsmarkersymbol.h:30
QgsFeatureRenderer::saveRendererData
void saveRendererData(QDomDocument &doc, QDomElement &element, const QgsReadWriteContext &context)
Saves generic renderer data into the specified element.
Definition: qgsrenderer.cpp:204
QgsFeatureRenderer::clone
virtual QgsFeatureRenderer * clone() const =0
Create a deep copy of this renderer.
RENDERER_TAG_NAME
#define RENDERER_TAG_NAME
Definition: qgsrenderer.h:50
QgsPointDistanceRenderer::mLabelColor
QColor mLabelColor
Label text color.
Definition: qgspointdistancerenderer.h:252
QgsPointDistanceRenderer
An abstract base class for distance based point renderers (e.g., clusterer and displacement renderers...
Definition: qgspointdistancerenderer.h:41
QgsPointDistanceRenderer::setEmbeddedRenderer
void setEmbeddedRenderer(QgsFeatureRenderer *r) override
Sets an embedded renderer (subrenderer) for this feature renderer.
Definition: qgspointdistancerenderer.cpp:168
QgsPointDistanceRenderer::mToleranceMapUnitScale
QgsMapUnitScale mToleranceMapUnitScale
Map unit scale for distance tolerance.
Definition: qgspointdistancerenderer.h:247
QgsMarkerSymbolLayer::setOffset
void setOffset(QPointF offset)
Sets the marker's offset, which is the horizontal and vertical displacement which the rendered marker...
Definition: qgssymbollayer.h:842
QgsPointClusterRenderer::QgsPointClusterRenderer
QgsPointClusterRenderer()
Definition: qgspointclusterrenderer.cpp:30
QgsSymbol::startRender
void startRender(QgsRenderContext &context, const QgsFields &fields=QgsFields())
Begins the rendering process for the symbol.
Definition: qgssymbol.cpp:794
QgsFontMarkerSymbolLayer::setFontFamily
void setFontFamily(const QString &family)
Sets the font family for the font which will be used to render the point.
Definition: qgsmarkersymbollayer.h:925
QgsPointDistanceRenderer::setToleranceMapUnitScale
void setToleranceMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale object for the distance tolerance.
Definition: qgspointdistancerenderer.h:221
QgsPointClusterRenderer::accept
bool accept(QgsStyleEntityVisitorInterface *visitor) const override
Accepts the specified symbology visitor, causing it to visit all symbols associated with the renderer...
Definition: qgspointclusterrenderer.cpp:159
QgsPointDistanceRenderer::tolerance
double tolerance() const
Returns the tolerance distance for grouping points.
Definition: qgspointdistancerenderer.h:195
QgsPointDistanceRenderer::setToleranceUnit
void setToleranceUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the tolerance distance.
Definition: qgspointdistancerenderer.h:204
QgsPointDistanceRenderer::accept
bool accept(QgsStyleEntityVisitorInterface *visitor) const override
Accepts the specified symbology visitor, causing it to visit all symbols associated with the renderer...
Definition: qgspointdistancerenderer.cpp:218
QgsFeatureRenderer
Definition: qgsrenderer.h:101
QgsPointDisplacementRenderer
A renderer that automatically displaces points with the same geographic location.
Definition: qgspointdisplacementrenderer.h:30
QgsPointDistanceRenderer::stopRender
void stopRender(QgsRenderContext &context) override
Must be called when a render cycle has finished, to allow the renderer to clean up.
Definition: qgspointdistancerenderer.cpp:351
qgsmarkersymbol.h
QgsFontMarkerSymbolLayer
Definition: qgsmarkersymbollayer.h:860
QgsPointDistanceRenderer::setLabelFont
void setLabelFont(const QFont &font)
Sets the font used for labeling points.
Definition: qgspointdistancerenderer.h:137
qgspointdisplacementrenderer.h
qgsproperty.h
QgsPointDistanceRenderer::setMinimumLabelScale
void setMinimumLabelScale(double scale)
Sets the minimum map scale (i.e.
Definition: qgspointdistancerenderer.h:153
QgsPointDistanceRenderer::setTolerance
void setTolerance(double distance)
Sets the tolerance distance for grouping points.
Definition: qgspointdistancerenderer.h:187
QgsStyleEntityVisitorInterface::visit
virtual bool visit(const QgsStyleEntityVisitorInterface::StyleLeaf &entity)
Called when the visitor will visit a style entity.
Definition: qgsstyleentityvisitor.h:153
QgsMarkerSymbolLayer::setSize
virtual void setSize(double size)
Sets the symbol size.
Definition: qgssymbollayer.h:777
qgspointclusterrenderer.h
QgsPointClusterRenderer::setClusterSymbol
void setClusterSymbol(QgsMarkerSymbol *symbol)
Sets the symbol for rendering clustered groups.
Definition: qgspointclusterrenderer.cpp:174
QgsPointDistanceRenderer::startRender
void startRender(QgsRenderContext &context, const QgsFields &fields) override
Must be called when a new render cycle is started.
Definition: qgspointdistancerenderer.cpp:321
QgsMarkerSymbol::renderPoint
void renderPoint(QPointF point, const QgsFeature *f, QgsRenderContext &context, int layer=-1, bool selected=false)
Renders the symbol at the specified point, using the given render context.
Definition: qgsmarkersymbol.cpp:447
QgsSymbolLayerUtils::saveSymbol
static QDomElement saveSymbol(const QString &symbolName, const QgsSymbol *symbol, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a symbol definition to XML.
Definition: qgssymbollayerutils.cpp:1397
QgsSymbolLayerUtils::decodeMapUnitScale
static QgsMapUnitScale decodeMapUnitScale(const QString &str)
Definition: qgssymbollayerutils.cpp:676
QgsPointDistanceRenderer::mTolerance
double mTolerance
Distance tolerance. Points that are closer together than this distance are considered clustered.
Definition: qgspointdistancerenderer.h:243
QgsSymbolLayer::setDataDefinedProperty
virtual void setDataDefinedProperty(Property key, const QgsProperty &property)
Sets a data defined property for the layer.
Definition: qgssymbollayer.cpp:126
qgsstyleentityvisitor.h
QgsPointDistanceRenderer::usedAttributes
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns a list of attributes required by this renderer.
Definition: qgspointdistancerenderer.cpp:227
QgsPointClusterRenderer::stopRender
void stopRender(QgsRenderContext &context) override
Must be called when a render cycle has finished, to allow the renderer to clean up.
Definition: qgspointclusterrenderer.cpp:90