QGIS API Documentation  3.18.1-Zürich (202f1bf7e5)
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 "qgsfield.h"
22 #include "qgsstyle.h"
24 #include "qgssymbollayerutils.h"
25 #include "qgsvectorlayer.h"
26 #include "qgsguiutils.h"
27 #include "qgsapplication.h"
28 
30 {
31  return new QgsPointClusterRendererWidget( layer, style, renderer );
32 }
33 
35  : QgsRendererWidget( layer, style )
36 
37 {
38  if ( !layer )
39  {
40  return;
41  }
42 
43  //the renderer only applies to point vector layers
45  {
46  //setup blank dialog
47  mRenderer = nullptr;
48  setupBlankUi( layer->name() );
49  return;
50  }
51  setupUi( this );
52  connect( mRendererComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsPointClusterRendererWidget::mRendererComboBox_currentIndexChanged );
53  connect( mDistanceSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsPointClusterRendererWidget::mDistanceSpinBox_valueChanged );
54  connect( mDistanceUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointClusterRendererWidget::mDistanceUnitWidget_changed );
55  connect( mRendererSettingsButton, &QPushButton::clicked, this, &QgsPointClusterRendererWidget::mRendererSettingsButton_clicked );
56  this->layout()->setContentsMargins( 0, 0, 0, 0 );
57 
60 
61  mCenterSymbolToolButton->setSymbolType( QgsSymbol::Marker );
62 
63  if ( renderer )
64  {
66  }
67  if ( !mRenderer )
68  {
69  mRenderer = new QgsPointClusterRenderer();
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  QString rendererName = mRenderer->embeddedRenderer()->type();
97  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 {
113  delete mRenderer;
114 }
115 
117 {
118  return mRenderer;
119 }
120 
122 {
124  if ( mDistanceUnitWidget )
125  mDistanceUnitWidget->setMapCanvas( context.mapCanvas() );
126  if ( mCenterSymbolToolButton )
127  {
128  mCenterSymbolToolButton->setMapCanvas( context.mapCanvas() );
129  mCenterSymbolToolButton->setMessageBar( context.messageBar() );
130  }
131 }
132 
133 void QgsPointClusterRendererWidget::mRendererComboBox_currentIndexChanged( int index )
134 {
135  QString rendererId = mRendererComboBox->itemData( index ).toString();
137  if ( m )
138  {
139  // unfortunately renderer conversion is only available through the creation of a widget...
140  std::unique_ptr< QgsFeatureRenderer > oldRenderer( mRenderer->embeddedRenderer()->clone() );
141  QgsRendererWidget *tempRenderWidget = m->createRendererWidget( mLayer, mStyle, oldRenderer.get() );
142  mRenderer->setEmbeddedRenderer( tempRenderWidget->renderer()->clone() );
143  delete tempRenderWidget;
144  }
145  emit widgetChanged();
146 }
147 
148 void QgsPointClusterRendererWidget::mRendererSettingsButton_clicked()
149 {
150  if ( !mRenderer )
151  return;
152 
154  if ( m )
155  {
157  w->setPanelTitle( tr( "Renderer Settings" ) );
158 
162  QList< QgsExpressionContextScope > scopes = mContext.additionalExpressionContextScopes();
163  scopes << scope;
166  w->setContext( context );
167  connect( w, &QgsPanelWidget::widgetChanged, this, &QgsPointClusterRendererWidget::updateRendererFromWidget );
168  w->setDockMode( this->dockMode() );
169  openPanel( w );
170  }
171 }
172 
173 void QgsPointClusterRendererWidget::mDistanceSpinBox_valueChanged( double d )
174 {
175  if ( mRenderer )
176  {
177  mRenderer->setTolerance( d );
178  }
179  emit widgetChanged();
180 }
181 
182 void QgsPointClusterRendererWidget::mDistanceUnitWidget_changed()
183 {
184  if ( mRenderer )
185  {
186  mRenderer->setToleranceUnit( mDistanceUnitWidget->unit() );
187  mRenderer->setToleranceMapUnitScale( mDistanceUnitWidget->getMapUnitScale() );
188  }
189  emit widgetChanged();
190 }
191 
192 void QgsPointClusterRendererWidget::blockAllSignals( bool block )
193 {
194  mRendererComboBox->blockSignals( block );
195  mCenterSymbolToolButton->blockSignals( block );
196  mDistanceSpinBox->blockSignals( block );
197  mDistanceUnitWidget->blockSignals( block );
198 }
199 
201 {
203  if ( auto *lExpressionContext = mContext.expressionContext() )
204  context = *lExpressionContext;
205  else
210  QList< QgsExpressionContextScope > scopes = mContext.additionalExpressionContextScopes();
211  scopes << scope;
212  const auto constScopes = scopes;
213  for ( const QgsExpressionContextScope &s : constScopes )
214  {
216  }
217  return context;
218 }
219 
220 void QgsPointClusterRendererWidget::centerSymbolChanged()
221 {
222  mRenderer->setClusterSymbol( mCenterSymbolToolButton->clonedSymbol< QgsMarkerSymbol >() );
223  emit widgetChanged();
224 }
225 
226 void QgsPointClusterRendererWidget::updateRendererFromWidget()
227 {
228  QgsRendererWidget *w = qobject_cast<QgsRendererWidget *>( sender() );
229  if ( !w )
230  return;
231 
232  mRenderer->setEmbeddedRenderer( w->renderer()->clone() );
233  emit widgetChanged();
234 }
235 
236 void QgsPointClusterRendererWidget::setupBlankUi( const QString &layerName )
237 {
238  QGridLayout *layout = new QGridLayout( this );
239  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 );
240  layout->addWidget( label );
241 }
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.
virtual QgsFeatureRenderer * clone() const =0
Create a deep copy of this renderer.
QString type() const
Definition: qgsrenderer.h:141
QString name
Definition: qgsmaplayer.h:88
A marker symbol type, for rendering Point and MultiPoint geometries.
Definition: qgssymbol.h:1004
QgsMarkerSymbol * clone() const override
Returns a deep copy of this symbol.
Definition: qgssymbol.cpp:2036
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.
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.
A renderer that automatically clusters points with the same geographic position.
void setClusterSymbol(QgsMarkerSymbol *symbol)
Sets the symbol for rendering clustered groups.
QgsMarkerSymbol * clusterSymbol()
Returns the symbol used for rendering clustered groups (but not ownership of the symbol).
static QgsPointClusterRenderer * convertFromRenderer(const QgsFeatureRenderer *renderer)
Creates a QgsPointClusterRenderer from an existing renderer.
QgsUnitTypes::RenderUnit toleranceUnit() const
Returns the units for the tolerance distance.
double tolerance() const
Returns the tolerance distance for grouping points.
const QgsMapUnitScale & toleranceMapUnitScale() const
Returns the map unit scale object for the distance tolerance.
void setEmbeddedRenderer(QgsFeatureRenderer *r) override
Sets an embedded renderer (subrenderer) for this feature renderer.
void setToleranceUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the tolerance distance.
const QgsFeatureRenderer * embeddedRenderer() const override
Returns the current embedded renderer (subrenderer) for this feature renderer.
void setToleranceMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale object for the distance tolerance.
void setTolerance(double distance)
Sets the tolerance distance for grouping points.
Stores metadata about one renderer class.
@ PointLayer
Compatible with point layers.
QIcon icon() const
Returns an icon representing the renderer.
virtual QgsRendererWidget * createRendererWidget(QgsVectorLayer *layer, QgsStyle *style, QgsFeatureRenderer *oldRenderer)
Returns new instance of settings widget for the renderer.
QString visibleName() const
Returns a friendly display name of 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.
virtual QgsFeatureRenderer * renderer()=0
Returns pointer to the renderer (no transfer of ownership)
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...
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.
@ Marker
Marker symbol.
Definition: qgssymbol.h:88
QList< QgsUnitTypes::RenderUnit > RenderUnitList
List of render units.
Definition: qgsunittypes.h:239
@ RenderPoints
Points (e.g., for font sizes)
Definition: qgsunittypes.h:172
@ RenderPixels
Pixels.
Definition: qgsunittypes.h:170
@ RenderInches
Inches.
Definition: qgsunittypes.h:173
@ RenderMillimeters
Millimeters.
Definition: qgsunittypes.h:168
@ RenderMapUnits
Map units.
Definition: qgsunittypes.h:169
Represents a vector layer which manages a vector based data sets.
Q_INVOKABLE QgsWkbTypes::Type wkbType() const FINAL
Returns the WKBType or WKBUnknown in case of error.
static Type flatType(Type type) SIP_HOLDGIL
Returns the flat type for a WKB type.
Definition: qgswkbtypes.h:702
Single variable definition for use within a QgsExpressionContextScope.