QGIS API Documentation  3.4.15-Madeira (e83d02e274)
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 
29 {
30  return new QgsPointClusterRendererWidget( layer, style, renderer );
31 }
32 
34  : QgsRendererWidget( layer, style )
35 
36 {
37  if ( !layer )
38  {
39  return;
40  }
41 
42  //the renderer only applies to point vector layers
44  {
45  //setup blank dialog
46  mRenderer = nullptr;
47  setupBlankUi( layer->name() );
48  return;
49  }
50  setupUi( this );
51  connect( mRendererComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsPointClusterRendererWidget::mRendererComboBox_currentIndexChanged );
52  connect( mDistanceSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsPointClusterRendererWidget::mDistanceSpinBox_valueChanged );
53  connect( mDistanceUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointClusterRendererWidget::mDistanceUnitWidget_changed );
54  connect( mRendererSettingsButton, &QPushButton::clicked, this, &QgsPointClusterRendererWidget::mRendererSettingsButton_clicked );
55  this->layout()->setContentsMargins( 0, 0, 0, 0 );
56 
59 
60  mCenterSymbolToolButton->setSymbolType( QgsSymbol::Marker );
61 
62  if ( renderer )
63  {
64  mRenderer = QgsPointClusterRenderer::convertFromRenderer( renderer );
65  }
66  if ( !mRenderer )
67  {
68  mRenderer = new QgsPointClusterRenderer();
69  }
70 
71  blockAllSignals( true );
72 
73  //insert possible renderer types
75  QStringList::const_iterator it = rendererList.constBegin();
76  for ( ; it != rendererList.constEnd(); ++it )
77  {
78  if ( *it != QLatin1String( "pointDisplacement" ) && *it != QLatin1String( "pointCluster" ) && *it != QLatin1String( "heatmapRenderer" ) )
79  {
81  mRendererComboBox->addItem( m->icon(), m->visibleName(), *it );
82  }
83  }
84 
85  mDistanceSpinBox->setValue( mRenderer->tolerance() );
86  mDistanceUnitWidget->setUnit( mRenderer->toleranceUnit() );
87  mDistanceUnitWidget->setMapUnitScale( mRenderer->toleranceMapUnitScale() );
88  mCenterSymbolToolButton->setSymbol( mRenderer->clusterSymbol()->clone() );
89 
90  blockAllSignals( false );
91 
92  //set the appropriate renderer dialog
93  if ( mRenderer->embeddedRenderer() )
94  {
95  QString rendererName = mRenderer->embeddedRenderer()->type();
96  int rendererIndex = mRendererComboBox->findData( rendererName );
97  if ( rendererIndex != -1 )
98  {
99  mRendererComboBox->setCurrentIndex( rendererIndex );
100  mRendererComboBox_currentIndexChanged( rendererIndex );
101  }
102  }
103 
104  connect( mCenterSymbolToolButton, &QgsSymbolButton::changed, this, &QgsPointClusterRendererWidget::centerSymbolChanged );
105  mCenterSymbolToolButton->setDialogTitle( tr( "Cluster symbol" ) );
106  mCenterSymbolToolButton->setLayer( mLayer );
107  mCenterSymbolToolButton->registerExpressionContextGenerator( this );
108 }
109 
111 {
112  delete mRenderer;
113 }
114 
116 {
117  return mRenderer;
118 }
119 
121 {
123  if ( mDistanceUnitWidget )
124  mDistanceUnitWidget->setMapCanvas( context.mapCanvas() );
125  if ( mCenterSymbolToolButton )
126  mCenterSymbolToolButton->setMapCanvas( context.mapCanvas() );
127 }
128 
129 void QgsPointClusterRendererWidget::mRendererComboBox_currentIndexChanged( int index )
130 {
131  QString rendererId = mRendererComboBox->itemData( index ).toString();
133  if ( m )
134  {
135  // unfortunately renderer conversion is only available through the creation of a widget...
136  QgsRendererWidget *tempRenderWidget = m->createRendererWidget( mLayer, mStyle, mRenderer->embeddedRenderer()->clone() );
137  mRenderer->setEmbeddedRenderer( tempRenderWidget->renderer()->clone() );
138  delete tempRenderWidget;
139  }
140  emit widgetChanged();
141 }
142 
143 void QgsPointClusterRendererWidget::mRendererSettingsButton_clicked()
144 {
145  if ( !mRenderer )
146  return;
147 
149  if ( m )
150  {
152  w->setPanelTitle( tr( "Renderer Settings" ) );
153 
157  QList< QgsExpressionContextScope > scopes = mContext.additionalExpressionContextScopes();
158  scopes << scope;
160  context.setAdditionalExpressionContextScopes( scopes );
161  w->setContext( context );
162  connect( w, &QgsPanelWidget::widgetChanged, this, &QgsPointClusterRendererWidget::updateRendererFromWidget );
163  w->setDockMode( this->dockMode() );
164  openPanel( w );
165  }
166 }
167 
168 void QgsPointClusterRendererWidget::mDistanceSpinBox_valueChanged( double d )
169 {
170  if ( mRenderer )
171  {
172  mRenderer->setTolerance( d );
173  }
174  emit widgetChanged();
175 }
176 
177 void QgsPointClusterRendererWidget::mDistanceUnitWidget_changed()
178 {
179  if ( mRenderer )
180  {
181  mRenderer->setToleranceUnit( mDistanceUnitWidget->unit() );
182  mRenderer->setToleranceMapUnitScale( mDistanceUnitWidget->getMapUnitScale() );
183  }
184  emit widgetChanged();
185 }
186 
187 void QgsPointClusterRendererWidget::blockAllSignals( bool block )
188 {
189  mRendererComboBox->blockSignals( block );
190  mCenterSymbolToolButton->blockSignals( block );
191  mDistanceSpinBox->blockSignals( block );
192  mDistanceUnitWidget->blockSignals( block );
193 }
194 
196 {
198  if ( mContext.expressionContext() )
199  context = *mContext.expressionContext();
200  else
205  QList< QgsExpressionContextScope > scopes = mContext.additionalExpressionContextScopes();
206  scopes << scope;
207  Q_FOREACH ( const QgsExpressionContextScope &s, scopes )
208  {
209  context << new QgsExpressionContextScope( s );
210  }
211  return context;
212 }
213 
214 void QgsPointClusterRendererWidget::centerSymbolChanged()
215 {
216  mRenderer->setClusterSymbol( mCenterSymbolToolButton->clonedSymbol< QgsMarkerSymbol >() );
217  emit widgetChanged();
218 }
219 
220 void QgsPointClusterRendererWidget::updateRendererFromWidget()
221 {
222  QgsRendererWidget *w = qobject_cast<QgsRendererWidget *>( sender() );
223  if ( !w )
224  return;
225 
226  mRenderer->setEmbeddedRenderer( w->renderer()->clone() );
227  emit widgetChanged();
228 }
229 
230 void QgsPointClusterRendererWidget::setupBlankUi( const QString &layerName )
231 {
232  QGridLayout *layout = new QGridLayout( this );
233  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 );
234  layout->addWidget( label );
235 }
void openPanel(QgsPanelWidget *panel)
Open a panel or dialog depending on dock mode setting If dock mode is true this method will emit the ...
QStringList renderersList(QgsRendererAbstractMetadata::LayerTypes layerTypes=QgsRendererAbstractMetadata::All) const
Returns a list of available renderers.
static const QString EXPR_CLUSTER_COLOR
Inbuilt variable name for cluster color variable.
QgsUnitTypes::RenderUnit toleranceUnit() const
Returns the units for the tolerance distance.
QString type() const
Definition: qgsrenderer.h:129
Single variable definition for use within a QgsExpressionContextScope.
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.
const QgsMapUnitScale & toleranceMapUnitScale() const
Returns the map unit scale object for the distance tolerance.
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.
QgsMapCanvas * mapCanvas() const
Returns the map canvas associated with the widget.
QList< QgsUnitTypes::RenderUnit > RenderUnitList
List of render units.
Definition: qgsunittypes.h:183
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
A marker symbol type, for rendering Point and MultiPoint geometries.
Definition: qgssymbol.h:732
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.
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...
points (e.g., for font sizes)
Definition: qgsunittypes.h:117
A renderer that automatically clusters points with the same geographic position.
QgsExpressionContext * expressionContext() const
Returns the expression context used for the widget, if set.
QgsRendererAbstractMetadata * rendererMetadata(const QString &rendererName)
Returns the metadata for a specified 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.
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.
QgsSymbolWidgetContext mContext
Context in which widget is shown.
QgsPointClusterRendererWidget(QgsVectorLayer *layer, QgsStyle *style, QgsFeatureRenderer *renderer)
Constructor for QgsPointClusterRendererWidget.
Stores metadata about one renderer class.
static const QString EXPR_CLUSTER_SIZE
Inbuilt variable name for cluster size variable.
QList< QgsExpressionContextScope > additionalExpressionContextScopes() const
Returns the list of additional expression context scopes to show as available within the layer...
QString name
Definition: qgsmaplayer.h:67
QList< QgsExpressionContextScope * > globalProjectAtlasMapLayerScopes(const QgsMapLayer *layer) const
Returns list of scopes: global, project, atlas, map, layer.
void appendScopes(const QList< QgsExpressionContextScope * > &scopes)
Appends a list of scopes to the end of the context.
QgsSymbolWidgetContext context() const
Returns the context in which the renderer widget is shown, e.g., the associated map canvas and expres...
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:565
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:1590
double tolerance() const
Returns the tolerance distance for grouping points.
static QgsRendererWidget * create(QgsVectorLayer *layer, QgsStyle *style, QgsFeatureRenderer *renderer)
Returns a new QgsPointClusterRendererWidget.