QGIS API Documentation 4.1.0-Master (5bf3c20f3c9)
Loading...
Searching...
No Matches
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
19
20#include "qgsapplication.h"
21#include "qgsmarkersymbol.h"
23#include "qgsrendererregistry.h"
24#include "qgsstyle.h"
26#include "qgsvectorlayer.h"
27
28#include <QString>
29
30#include "moc_qgspointclusterrendererwidget.cpp"
31
32using namespace Qt::StringLiterals;
33
38
40 : QgsRendererWidget( layer, style )
41
42{
43 if ( !layer )
44 {
45 return;
46 }
47
48 //the renderer only applies to point vector layers
50 {
51 //setup blank dialog
52 mRenderer = nullptr;
53 setupBlankUi( layer->name() );
54 return;
55 }
56 setupUi( this );
57 connect( mRendererComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsPointClusterRendererWidget::mRendererComboBox_currentIndexChanged );
58 connect( mDistanceSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsPointClusterRendererWidget::mDistanceSpinBox_valueChanged );
59 connect( mDistanceUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointClusterRendererWidget::mDistanceUnitWidget_changed );
60 connect( mRendererSettingsButton, &QPushButton::clicked, this, &QgsPointClusterRendererWidget::mRendererSettingsButton_clicked );
61 this->layout()->setContentsMargins( 0, 0, 0, 0 );
62
63 mDistanceUnitWidget->setUnits(
65 );
66
67 mCenterSymbolToolButton->setSymbolType( Qgis::SymbolType::Marker );
68
69 if ( renderer )
70 {
72 }
73 if ( !mRenderer )
74 {
75 mRenderer = std::make_unique<QgsPointClusterRenderer>();
76 if ( renderer )
77 renderer->copyRendererData( mRenderer.get() );
78 }
79
80 blockAllSignals( true );
81
82 //insert possible renderer types
84 QStringList::const_iterator it = rendererList.constBegin();
85 for ( ; it != rendererList.constEnd(); ++it )
86 {
87 if ( *it != "pointDisplacement"_L1 && *it != "pointCluster"_L1 && *it != "heatmapRenderer"_L1 )
88 {
90 mRendererComboBox->addItem( m->icon(), m->visibleName(), *it );
91 }
92 }
93
94 mDistanceSpinBox->setValue( mRenderer->tolerance() );
95 mDistanceUnitWidget->setUnit( mRenderer->toleranceUnit() );
96 mDistanceUnitWidget->setMapUnitScale( mRenderer->toleranceMapUnitScale() );
97 mCenterSymbolToolButton->setSymbol( mRenderer->clusterSymbol()->clone() );
98
99 blockAllSignals( false );
100
101 //set the appropriate renderer dialog
102 if ( mRenderer->embeddedRenderer() )
103 {
104 const QString rendererName = mRenderer->embeddedRenderer()->type();
105 const int rendererIndex = mRendererComboBox->findData( rendererName );
106 if ( rendererIndex != -1 )
107 {
108 mRendererComboBox->setCurrentIndex( rendererIndex );
109 mRendererComboBox_currentIndexChanged( rendererIndex );
110 }
111 }
112
113 connect( mCenterSymbolToolButton, &QgsSymbolButton::changed, this, &QgsPointClusterRendererWidget::centerSymbolChanged );
114 mCenterSymbolToolButton->setDialogTitle( tr( "Cluster symbol" ) );
115 mCenterSymbolToolButton->setLayer( mLayer );
116 mCenterSymbolToolButton->registerExpressionContextGenerator( this );
117}
118
120
122{
123 return mRenderer.get();
124}
125
127{
129 if ( mDistanceUnitWidget )
130 mDistanceUnitWidget->setMapCanvas( context.mapCanvas() );
131 if ( mCenterSymbolToolButton )
132 {
133 mCenterSymbolToolButton->setMapCanvas( context.mapCanvas() );
134 mCenterSymbolToolButton->setMessageBar( context.messageBar() );
135 }
136}
137
138void QgsPointClusterRendererWidget::mRendererComboBox_currentIndexChanged( int index )
139{
140 const QString rendererId = mRendererComboBox->itemData( index ).toString();
142 if ( m )
143 {
144 // unfortunately renderer conversion is only available through the creation of a widget...
145 const std::unique_ptr<QgsFeatureRenderer> oldRenderer( mRenderer->embeddedRenderer()->clone() );
146 QgsRendererWidget *tempRenderWidget = m->createRendererWidget( mLayer, mStyle, oldRenderer.get() );
147 mRenderer->setEmbeddedRenderer( tempRenderWidget->renderer()->clone() );
148 delete tempRenderWidget;
149 }
150 emit widgetChanged();
151}
152
153void QgsPointClusterRendererWidget::mRendererSettingsButton_clicked()
154{
155 if ( !mRenderer )
156 return;
157
158 QgsRendererAbstractMetadata *m = QgsApplication::rendererRegistry()->rendererMetadata( mRenderer->embeddedRenderer()->type() );
159 if ( m )
160 {
161 QgsRendererWidget *w = m->createRendererWidget( mLayer, mStyle, mRenderer->embeddedRenderer()->clone() );
162 w->setPanelTitle( tr( "Renderer Settings" ) );
163
164 QgsExpressionContextScope scope;
165 scope.addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_CLUSTER_COLOR, "", true ) );
166 scope.addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_CLUSTER_SIZE, 0, true ) );
167 QList<QgsExpressionContextScope> scopes = mContext.additionalExpressionContextScopes();
168 scopes << scope;
169 QgsSymbolWidgetContext context = mContext;
170 context.setAdditionalExpressionContextScopes( scopes );
171 w->setContext( context );
173 connect( w, &QgsPanelWidget::widgetChanged, this, &QgsPointClusterRendererWidget::updateRendererFromWidget );
174 w->setDockMode( this->dockMode() );
175 openPanel( w );
176 }
177}
178
179void QgsPointClusterRendererWidget::mDistanceSpinBox_valueChanged( double d )
180{
181 if ( mRenderer )
182 {
183 mRenderer->setTolerance( d );
184 }
185 emit widgetChanged();
186}
187
188void QgsPointClusterRendererWidget::mDistanceUnitWidget_changed()
189{
190 if ( mRenderer )
191 {
192 mRenderer->setToleranceUnit( mDistanceUnitWidget->unit() );
193 mRenderer->setToleranceMapUnitScale( mDistanceUnitWidget->getMapUnitScale() );
194 }
195 emit widgetChanged();
196}
197
198void QgsPointClusterRendererWidget::blockAllSignals( bool block )
199{
200 mRendererComboBox->blockSignals( block );
201 mCenterSymbolToolButton->blockSignals( block );
202 mDistanceSpinBox->blockSignals( block );
203 mDistanceUnitWidget->blockSignals( block );
204}
205
207{
209 if ( auto *lExpressionContext = mContext.expressionContext() )
210 context = *lExpressionContext;
211 else
212 context.appendScopes( mContext.globalProjectAtlasMapLayerScopes( mLayer ) );
216 QList<QgsExpressionContextScope> scopes = mContext.additionalExpressionContextScopes();
217 scopes << scope;
218 const auto constScopes = scopes;
219 for ( const QgsExpressionContextScope &s : constScopes )
220 {
222 }
224 return context;
225}
226
227void QgsPointClusterRendererWidget::centerSymbolChanged()
228{
229 mRenderer->setClusterSymbol( mCenterSymbolToolButton->clonedSymbol<QgsMarkerSymbol>() );
230 emit widgetChanged();
231}
232
233void QgsPointClusterRendererWidget::updateRendererFromWidget()
234{
235 QgsRendererWidget *w = qobject_cast<QgsRendererWidget *>( sender() );
236 if ( !w )
237 return;
238
239 mRenderer->setEmbeddedRenderer( w->renderer()->clone() );
240 emit widgetChanged();
241}
242
243void QgsPointClusterRendererWidget::setupBlankUi( const QString &layerName )
244{
245 QGridLayout *layout = new QGridLayout( this );
246 QLabel *label
247 = 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 );
248 layout->addWidget( label );
249}
@ Point
Points.
Definition qgis.h:380
@ Millimeters
Millimeters.
Definition qgis.h:5341
@ Points
Points (e.g., for font sizes).
Definition qgis.h:5345
@ MapUnits
Map units.
Definition qgis.h:5342
@ Pixels
Pixels.
Definition qgis.h:5343
@ Inches
Inches.
Definition qgis.h:5346
@ MetersInMapUnits
Meters value as Map units.
Definition qgis.h:5348
@ Marker
Marker symbol.
Definition qgis.h:637
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.
Abstract base class for all 2D vector feature renderers.
virtual QgsFeatureRenderer * clone() const =0
Create a deep copy of this renderer.
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 ...
bool dockMode() const
Returns the dock mode state.
void widgetChanged()
Emitted when the widget state changes.
void setPanelTitle(const QString &panelTitle)
Set the title of the panel when shown in the interface.
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.
QgsRendererWidget(QgsVectorLayer *layer, QgsStyle *style)
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
A database of saved style entities, including symbols, color ramps, text formats and others.
Definition qgsstyle.h:89
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,...
void changed()
Emitted when the selected unit is changed, or the definition of the map unit scale is changed.
Represents a vector layer which manages a vector based dataset.
Q_INVOKABLE Qgis::WkbType wkbType() const final
Returns the WKBType or WKBUnknown in case of error.
static Qgis::GeometryType geometryType(Qgis::WkbType type)
Returns the geometry type for a WKB type, e.g., both MultiPolygon and CurvePolygon would have a Polyg...
Single variable definition for use within a QgsExpressionContextScope.