QGIS API Documentation  3.10.0-A Coruña (6c816b4204)
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  {
65  mRenderer = QgsPointClusterRenderer::convertFromRenderer( renderer );
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;
165  context.setAdditionalExpressionContextScopes( scopes );
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 ( mContext.expressionContext() )
204  context = *mContext.expressionContext();
205  else
210  QList< QgsExpressionContextScope > scopes = mContext.additionalExpressionContextScopes();
211  scopes << scope;
212  const auto constScopes = scopes;
213  for ( const QgsExpressionContextScope &s : constScopes )
214  {
215  context << new QgsExpressionContextScope( s );
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 }
void openPanel(QgsPanelWidget *panel)
Open a panel or dialog depending on dock mode setting If dock mode is true this method will emit the ...
static const QString EXPR_CLUSTER_COLOR
Inbuilt variable name for cluster color variable.
Single variable definition for use within a QgsExpressionContextScope.
QList< QgsExpressionContextScope * > globalProjectAtlasMapLayerScopes(const QgsMapLayer *layer) const
Returns list of scopes: global, project, atlas, map, layer.
virtual QgsFeatureRenderer * renderer()=0
Returns pointer to the renderer (no transfer of ownership)
virtual void setContext(const QgsSymbolWidgetContext &context)
Sets the context in which the renderer widget is shown, e.g., the associated map canvas and expressio...
bool dockMode()
Returns the dock mode state.
void setClusterSymbol(QgsMarkerSymbol *symbol)
Sets the symbol for rendering clustered groups.
virtual QgsRendererWidget * createRendererWidget(QgsVectorLayer *layer, QgsStyle *style, QgsFeatureRenderer *oldRenderer)
Returns new instance of settings widget for the renderer.
QgsSymbolWidgetContext context() const
Returns the context in which the renderer widget is shown, e.g., the associated map canvas and expres...
void setContext(const QgsSymbolWidgetContext &context) override
Sets the context in which the renderer widget is shown, e.g., the associated map canvas and expressio...
QgsWkbTypes::Type wkbType() const FINAL
Returns the WKBType or WKBUnknown in case of error.
Base class for renderer settings widgets.
QgsMarkerSymbol * clusterSymbol()
Returns the symbol used for rendering clustered groups (but not ownership of the symbol).
void setTolerance(double distance)
Sets the tolerance distance for grouping points.
QgsVectorLayer * mLayer
void setToleranceMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale object for the distance tolerance.
void setToleranceUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the tolerance distance.
void changed()
Emitted when the symbol&#39;s settings are changed.
QStringList renderersList(QgsRendererAbstractMetadata::LayerTypes layerTypes=QgsRendererAbstractMetadata::All) const
Returns a list of available renderers.
QIcon icon() const
Returns an icon representing the renderer.
QList< QgsUnitTypes::RenderUnit > RenderUnitList
List of render units.
Definition: qgsunittypes.h:218
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
QgsUnitTypes::RenderUnit toleranceUnit() const
Returns the units for the tolerance distance.
A marker symbol type, for rendering Point and MultiPoint geometries.
Definition: qgssymbol.h:860
virtual void setDockMode(bool dockMode)
Set the widget in dock mode which tells the widget to emit panel widgets and not open dialogs...
static QgsPointClusterRenderer * convertFromRenderer(const QgsFeatureRenderer *renderer)
Creates a QgsPointClusterRenderer from an existing renderer.
QString type() const
Definition: qgsrenderer.h:130
Contains settings which reflect the context in which a symbol (or renderer) widget is shown...
Compatible with point layers.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
A renderer that automatically clusters points with the same geographic position.
QgsRendererAbstractMetadata * rendererMetadata(const QString &rendererName)
Returns the metadata for a specified renderer.
QString visibleName() const
Returns a friendly display name of the renderer.
Single scope for storing variables and functions for use within a QgsExpressionContext.
void setAdditionalExpressionContextScopes(const QList< QgsExpressionContextScope > &scopes)
Sets a list of additional expression context scopes to show as available within the layer...
void widgetChanged()
Emitted when the widget state changes.
double tolerance() const
Returns the tolerance distance for grouping points.
const QgsMapUnitScale & toleranceMapUnitScale() const
Returns the map unit scale object for the distance tolerance.
QgsMapCanvas * mapCanvas() const
Returns the map canvas associated with the widget.
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
Marker symbol.
Definition: qgssymbol.h:85
const QgsFeatureRenderer * embeddedRenderer() const override
Returns the current embedded renderer (subrenderer) for this feature renderer.
QgsExpressionContext * expressionContext() const
Returns the expression context used for the widget, if set.
QgsSymbolWidgetContext mContext
Context in which widget is shown.
QgsPointClusterRendererWidget(QgsVectorLayer *layer, QgsStyle *style, QgsFeatureRenderer *renderer)
Constructor for QgsPointClusterRendererWidget.
Points (e.g., for font sizes)
Definition: qgsunittypes.h:151
Stores metadata about one renderer class.
QgsMessageBar * messageBar() const
Returns the message bar associated with the widget.
static const QString EXPR_CLUSTER_SIZE
Inbuilt variable name for cluster size variable.
QString name
Definition: qgsmaplayer.h:83
void appendScopes(const QList< QgsExpressionContextScope *> &scopes)
Appends a list of scopes to the end of the context.
void setEmbeddedRenderer(QgsFeatureRenderer *r) override
Sets an embedded renderer (subrenderer) for this feature renderer.
Represents a vector layer which manages a vector based data sets.
static Type flatType(Type type)
Returns the flat type for a WKB type.
Definition: qgswkbtypes.h:576
void setPanelTitle(const QString &panelTitle)
Set the title of the panel when shown in the interface.
QgsFeatureRenderer * renderer() override
Returns pointer to the renderer (no transfer of ownership)
static QgsRendererRegistry * rendererRegistry()
Returns the application&#39;s renderer registry, used for managing vector layer renderers.
virtual QgsFeatureRenderer * clone() const =0
Create a deep copy of this renderer.
QgsMarkerSymbol * clone() const override
Returns a deep copy of this symbol.
Definition: qgssymbol.cpp:1708
static QgsRendererWidget * create(QgsVectorLayer *layer, QgsStyle *style, QgsFeatureRenderer *renderer)
Returns a new QgsPointClusterRendererWidget.
QList< QgsExpressionContextScope > additionalExpressionContextScopes() const
Returns the list of additional expression context scopes to show as available within the layer...