QGIS API Documentation 3.31.0-Master (9f23a2c1dc)
qgspointclusterrendererwidget.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgspointclusterrendererwidget.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 "qgsrendererregistry.h"
21#include "qgsstyle.h"
23#include "qgsvectorlayer.h"
24#include "qgsapplication.h"
25#include "qgsmarkersymbol.h"
26
28{
29 return new QgsPointClusterRendererWidget( layer, style, renderer );
30}
31
33 : QgsRendererWidget( layer, style )
34
35{
36 if ( !layer )
37 {
38 return;
39 }
40
41 //the renderer only applies to point vector layers
42 if ( QgsWkbTypes::geometryType( layer->wkbType() ) != Qgis::GeometryType::Point )
43 {
44 //setup blank dialog
45 mRenderer = nullptr;
46 setupBlankUi( layer->name() );
47 return;
48 }
49 setupUi( this );
50 connect( mRendererComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsPointClusterRendererWidget::mRendererComboBox_currentIndexChanged );
51 connect( mDistanceSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsPointClusterRendererWidget::mDistanceSpinBox_valueChanged );
52 connect( mDistanceUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointClusterRendererWidget::mDistanceUnitWidget_changed );
53 connect( mRendererSettingsButton, &QPushButton::clicked, this, &QgsPointClusterRendererWidget::mRendererSettingsButton_clicked );
54 this->layout()->setContentsMargins( 0, 0, 0, 0 );
55
56 mDistanceUnitWidget->setUnits( { Qgis::RenderUnit::Millimeters, Qgis::RenderUnit::MetersInMapUnits, Qgis::RenderUnit::MapUnits, Qgis::RenderUnit::Pixels,
57 Qgis::RenderUnit::Points, Qgis::RenderUnit::Inches } );
58
59 mCenterSymbolToolButton->setSymbolType( Qgis::SymbolType::Marker );
60
61 if ( renderer )
62 {
64 }
65 if ( !mRenderer )
66 {
67 mRenderer = std::make_unique< QgsPointClusterRenderer >();
68 if ( renderer )
69 renderer->copyRendererData( mRenderer.get() );
70 }
71
72 blockAllSignals( true );
73
74 //insert possible renderer types
76 QStringList::const_iterator it = rendererList.constBegin();
77 for ( ; it != rendererList.constEnd(); ++it )
78 {
79 if ( *it != QLatin1String( "pointDisplacement" ) && *it != QLatin1String( "pointCluster" ) && *it != QLatin1String( "heatmapRenderer" ) )
80 {
82 mRendererComboBox->addItem( m->icon(), m->visibleName(), *it );
83 }
84 }
85
86 mDistanceSpinBox->setValue( mRenderer->tolerance() );
87 mDistanceUnitWidget->setUnit( mRenderer->toleranceUnit() );
88 mDistanceUnitWidget->setMapUnitScale( mRenderer->toleranceMapUnitScale() );
89 mCenterSymbolToolButton->setSymbol( mRenderer->clusterSymbol()->clone() );
90
91 blockAllSignals( false );
92
93 //set the appropriate renderer dialog
94 if ( mRenderer->embeddedRenderer() )
95 {
96 const QString rendererName = mRenderer->embeddedRenderer()->type();
97 const int rendererIndex = mRendererComboBox->findData( rendererName );
98 if ( rendererIndex != -1 )
99 {
100 mRendererComboBox->setCurrentIndex( rendererIndex );
101 mRendererComboBox_currentIndexChanged( rendererIndex );
102 }
103 }
104
105 connect( mCenterSymbolToolButton, &QgsSymbolButton::changed, this, &QgsPointClusterRendererWidget::centerSymbolChanged );
106 mCenterSymbolToolButton->setDialogTitle( tr( "Cluster symbol" ) );
107 mCenterSymbolToolButton->setLayer( mLayer );
108 mCenterSymbolToolButton->registerExpressionContextGenerator( this );
109}
110
112
114{
115 return mRenderer.get();
116}
117
119{
121 if ( mDistanceUnitWidget )
122 mDistanceUnitWidget->setMapCanvas( context.mapCanvas() );
123 if ( mCenterSymbolToolButton )
124 {
125 mCenterSymbolToolButton->setMapCanvas( context.mapCanvas() );
126 mCenterSymbolToolButton->setMessageBar( context.messageBar() );
127 }
128}
129
130void QgsPointClusterRendererWidget::mRendererComboBox_currentIndexChanged( int index )
131{
132 const QString rendererId = mRendererComboBox->itemData( index ).toString();
134 if ( m )
135 {
136 // unfortunately renderer conversion is only available through the creation of a widget...
137 const std::unique_ptr< QgsFeatureRenderer > oldRenderer( mRenderer->embeddedRenderer()->clone() );
138 QgsRendererWidget *tempRenderWidget = m->createRendererWidget( mLayer, mStyle, oldRenderer.get() );
139 mRenderer->setEmbeddedRenderer( tempRenderWidget->renderer()->clone() );
140 delete tempRenderWidget;
141 }
142 emit widgetChanged();
143}
144
145void QgsPointClusterRendererWidget::mRendererSettingsButton_clicked()
146{
147 if ( !mRenderer )
148 return;
149
150 QgsRendererAbstractMetadata *m = QgsApplication::rendererRegistry()->rendererMetadata( mRenderer->embeddedRenderer()->type() );
151 if ( m )
152 {
153 QgsRendererWidget *w = m->createRendererWidget( mLayer, mStyle, mRenderer->embeddedRenderer()->clone() );
154 w->setPanelTitle( tr( "Renderer Settings" ) );
155
159 QList< QgsExpressionContextScope > scopes = mContext.additionalExpressionContextScopes();
160 scopes << scope;
163 w->setContext( context );
165 connect( w, &QgsPanelWidget::widgetChanged, this, &QgsPointClusterRendererWidget::updateRendererFromWidget );
166 w->setDockMode( this->dockMode() );
167 openPanel( w );
168 }
169}
170
171void QgsPointClusterRendererWidget::mDistanceSpinBox_valueChanged( double d )
172{
173 if ( mRenderer )
174 {
175 mRenderer->setTolerance( d );
176 }
177 emit widgetChanged();
178}
179
180void QgsPointClusterRendererWidget::mDistanceUnitWidget_changed()
181{
182 if ( mRenderer )
183 {
184 mRenderer->setToleranceUnit( mDistanceUnitWidget->unit() );
185 mRenderer->setToleranceMapUnitScale( mDistanceUnitWidget->getMapUnitScale() );
186 }
187 emit widgetChanged();
188}
189
190void QgsPointClusterRendererWidget::blockAllSignals( bool block )
191{
192 mRendererComboBox->blockSignals( block );
193 mCenterSymbolToolButton->blockSignals( block );
194 mDistanceSpinBox->blockSignals( block );
195 mDistanceUnitWidget->blockSignals( block );
196}
197
199{
201 if ( auto *lExpressionContext = mContext.expressionContext() )
202 context = *lExpressionContext;
203 else
208 QList< QgsExpressionContextScope > scopes = mContext.additionalExpressionContextScopes();
209 scopes << scope;
210 const auto constScopes = scopes;
211 for ( const QgsExpressionContextScope &s : constScopes )
212 {
214 }
215 return context;
216}
217
218void QgsPointClusterRendererWidget::centerSymbolChanged()
219{
220 mRenderer->setClusterSymbol( mCenterSymbolToolButton->clonedSymbol< QgsMarkerSymbol >() );
221 emit widgetChanged();
222}
223
224void QgsPointClusterRendererWidget::updateRendererFromWidget()
225{
226 QgsRendererWidget *w = qobject_cast<QgsRendererWidget *>( sender() );
227 if ( !w )
228 return;
229
230 mRenderer->setEmbeddedRenderer( w->renderer()->clone() );
231 emit widgetChanged();
232}
233
234void QgsPointClusterRendererWidget::setupBlankUi( const QString &layerName )
235{
236 QGridLayout *layout = new QGridLayout( this );
237 QLabel *label = new QLabel( tr( "The point cluster renderer only applies to (single) point layers. \n'%1' is not a (single) point layer and cannot be displayed by the point cluster renderer." ).arg( layerName ), this );
238 layout->addWidget( label );
239}
@ Marker
Marker symbol.
static QgsRendererRegistry * rendererRegistry()
Returns the application's renderer registry, used for managing vector layer renderers.
Single scope for storing variables and functions for use within a QgsExpressionContext.
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
static const QString EXPR_CLUSTER_SIZE
Inbuilt variable name for cluster size variable.
static const QString EXPR_CLUSTER_COLOR
Inbuilt variable name for cluster color variable.
void copyRendererData(QgsFeatureRenderer *destRenderer) const
Clones generic renderer data to another renderer.
Definition: qgsrenderer.cpp:46
virtual QgsFeatureRenderer * clone() const =0
Create a deep copy of this renderer.
QString name
Definition: qgsmaplayer.h:76
A marker symbol type, for rendering Point and MultiPoint geometries.
void openPanel(QgsPanelWidget *panel)
Open a panel or dialog depending on dock mode setting If dock mode is true this method will emit the ...
void widgetChanged()
Emitted when the widget state changes.
void setPanelTitle(const QString &panelTitle)
Set the title of the panel when shown in the interface.
bool dockMode()
Returns the dock mode state.
QgsPointClusterRendererWidget(QgsVectorLayer *layer, QgsStyle *style, QgsFeatureRenderer *renderer)
Constructor for QgsPointClusterRendererWidget.
~QgsPointClusterRendererWidget() override
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
void setContext(const QgsSymbolWidgetContext &context) override
Sets the context in which the renderer widget is shown, e.g., the associated map canvas and expressio...
QgsFeatureRenderer * renderer() override
Returns pointer to the renderer (no transfer of ownership)
static QgsRendererWidget * create(QgsVectorLayer *layer, QgsStyle *style, QgsFeatureRenderer *renderer)
Returns a new QgsPointClusterRendererWidget.
static QgsPointClusterRenderer * convertFromRenderer(const QgsFeatureRenderer *renderer)
Creates a QgsPointClusterRenderer from an existing renderer.
Stores metadata about one renderer class.
@ PointLayer
Compatible with point layers.
QIcon icon() const
Returns an icon representing the renderer.
QString visibleName() const
Returns a friendly display name of the renderer.
virtual QgsRendererWidget * createRendererWidget(QgsVectorLayer *layer, QgsStyle *style, QgsFeatureRenderer *oldRenderer)
Returns new instance of settings widget for the renderer.
QStringList renderersList(QgsRendererAbstractMetadata::LayerTypes layerTypes=QgsRendererAbstractMetadata::All) const
Returns a list of available renderers.
QgsRendererAbstractMetadata * rendererMetadata(const QString &rendererName)
Returns the metadata for a specified renderer.
Base class for renderer settings widgets.
void setDockMode(bool dockMode) override
Set the widget in dock mode which tells the widget to emit panel widgets and not open dialogs.
QgsSymbolWidgetContext mContext
Context in which widget is shown.
virtual void setContext(const QgsSymbolWidgetContext &context)
Sets the context in which the renderer widget is shown, e.g., the associated map canvas and expressio...
virtual QgsFeatureRenderer * renderer()=0
Returns pointer to the renderer (no transfer of ownership)
virtual void disableSymbolLevels()
Disables symbol level modification on the widget.
QgsSymbolWidgetContext context() const
Returns the context in which the renderer widget is shown, e.g., the associated map canvas and expres...
QgsVectorLayer * mLayer
void changed()
Emitted when the symbol's settings are changed.
Contains settings which reflect the context in which a symbol (or renderer) widget is shown,...
QList< QgsExpressionContextScope > additionalExpressionContextScopes() const
Returns the list of additional expression context scopes to show as available within the layer.
QList< QgsExpressionContextScope * > globalProjectAtlasMapLayerScopes(const QgsMapLayer *layer) const
Returns list of scopes: global, project, atlas, map, layer.
void setAdditionalExpressionContextScopes(const QList< QgsExpressionContextScope > &scopes)
Sets a list of additional expression context scopes to show as available within the layer.
QgsExpressionContext * expressionContext() const
Returns the expression context used for the widget, if set.
QgsMapCanvas * mapCanvas() const
Returns the map canvas associated with the widget.
QgsMessageBar * messageBar() const
Returns the message bar associated with the widget.
Represents a vector layer which manages a vector based data sets.
Q_INVOKABLE Qgis::WkbType wkbType() const FINAL
Returns the WKBType or WKBUnknown in case of error.
static Qgis::GeometryType geometryType(Qgis::WkbType type) SIP_HOLDGIL
Returns the geometry type for a WKB type, e.g., both MultiPolygon and CurvePolygon would have a Polyg...
Definition: qgswkbtypes.h:865
Single variable definition for use within a QgsExpressionContextScope.