QGIS API Documentation  3.23.0-Master (dd0cd13a00)
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 #include "qgsmarkersymbol.h"
29 
31 {
32  return new QgsPointClusterRendererWidget( layer, style, renderer );
33 }
34 
36  : QgsRendererWidget( layer, style )
37 
38 {
39  if ( !layer )
40  {
41  return;
42  }
43 
44  //the renderer only applies to point vector layers
46  {
47  //setup blank dialog
48  mRenderer = nullptr;
49  setupBlankUi( layer->name() );
50  return;
51  }
52  setupUi( this );
53  connect( mRendererComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsPointClusterRendererWidget::mRendererComboBox_currentIndexChanged );
54  connect( mDistanceSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsPointClusterRendererWidget::mDistanceSpinBox_valueChanged );
55  connect( mDistanceUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointClusterRendererWidget::mDistanceUnitWidget_changed );
56  connect( mRendererSettingsButton, &QPushButton::clicked, this, &QgsPointClusterRendererWidget::mRendererSettingsButton_clicked );
57  this->layout()->setContentsMargins( 0, 0, 0, 0 );
58 
61 
62  mCenterSymbolToolButton->setSymbolType( Qgis::SymbolType::Marker );
63 
64  if ( renderer )
65  {
67  }
68  if ( !mRenderer )
69  {
70  mRenderer = std::make_unique< QgsPointClusterRenderer >();
71  if ( renderer )
72  renderer->copyRendererData( mRenderer.get() );
73  }
74 
75  blockAllSignals( true );
76 
77  //insert possible renderer types
79  QStringList::const_iterator it = rendererList.constBegin();
80  for ( ; it != rendererList.constEnd(); ++it )
81  {
82  if ( *it != QLatin1String( "pointDisplacement" ) && *it != QLatin1String( "pointCluster" ) && *it != QLatin1String( "heatmapRenderer" ) )
83  {
85  mRendererComboBox->addItem( m->icon(), m->visibleName(), *it );
86  }
87  }
88 
89  mDistanceSpinBox->setValue( mRenderer->tolerance() );
90  mDistanceUnitWidget->setUnit( mRenderer->toleranceUnit() );
91  mDistanceUnitWidget->setMapUnitScale( mRenderer->toleranceMapUnitScale() );
92  mCenterSymbolToolButton->setSymbol( mRenderer->clusterSymbol()->clone() );
93 
94  blockAllSignals( false );
95 
96  //set the appropriate renderer dialog
97  if ( mRenderer->embeddedRenderer() )
98  {
99  const QString rendererName = mRenderer->embeddedRenderer()->type();
100  const int rendererIndex = mRendererComboBox->findData( rendererName );
101  if ( rendererIndex != -1 )
102  {
103  mRendererComboBox->setCurrentIndex( rendererIndex );
104  mRendererComboBox_currentIndexChanged( rendererIndex );
105  }
106  }
107 
108  connect( mCenterSymbolToolButton, &QgsSymbolButton::changed, this, &QgsPointClusterRendererWidget::centerSymbolChanged );
109  mCenterSymbolToolButton->setDialogTitle( tr( "Cluster symbol" ) );
110  mCenterSymbolToolButton->setLayer( mLayer );
111  mCenterSymbolToolButton->registerExpressionContextGenerator( this );
112 }
113 
115 
117 {
118  return mRenderer.get();
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  const QString rendererId = mRendererComboBox->itemData( index ).toString();
137  if ( m )
138  {
139  // unfortunately renderer conversion is only available through the creation of a widget...
140  const 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 
153  QgsRendererAbstractMetadata *m = QgsApplication::rendererRegistry()->rendererMetadata( mRenderer->embeddedRenderer()->type() );
154  if ( m )
155  {
156  QgsRendererWidget *w = m->createRendererWidget( mLayer, mStyle, mRenderer->embeddedRenderer()->clone() );
157  w->setPanelTitle( tr( "Renderer Settings" ) );
158 
162  QList< QgsExpressionContextScope > scopes = mContext.additionalExpressionContextScopes();
163  scopes << scope;
166  w->setContext( context );
167  w->disableSymbolLevels();
168  connect( w, &QgsPanelWidget::widgetChanged, this, &QgsPointClusterRendererWidget::updateRendererFromWidget );
169  w->setDockMode( this->dockMode() );
170  openPanel( w );
171  }
172 }
173 
174 void QgsPointClusterRendererWidget::mDistanceSpinBox_valueChanged( double d )
175 {
176  if ( mRenderer )
177  {
178  mRenderer->setTolerance( d );
179  }
180  emit widgetChanged();
181 }
182 
183 void QgsPointClusterRendererWidget::mDistanceUnitWidget_changed()
184 {
185  if ( mRenderer )
186  {
187  mRenderer->setToleranceUnit( mDistanceUnitWidget->unit() );
188  mRenderer->setToleranceMapUnitScale( mDistanceUnitWidget->getMapUnitScale() );
189  }
190  emit widgetChanged();
191 }
192 
193 void QgsPointClusterRendererWidget::blockAllSignals( bool block )
194 {
195  mRendererComboBox->blockSignals( block );
196  mCenterSymbolToolButton->blockSignals( block );
197  mDistanceSpinBox->blockSignals( block );
198  mDistanceUnitWidget->blockSignals( block );
199 }
200 
202 {
204  if ( auto *lExpressionContext = mContext.expressionContext() )
205  context = *lExpressionContext;
206  else
211  QList< QgsExpressionContextScope > scopes = mContext.additionalExpressionContextScopes();
212  scopes << scope;
213  const auto constScopes = scopes;
214  for ( const QgsExpressionContextScope &s : constScopes )
215  {
217  }
218  return context;
219 }
220 
221 void QgsPointClusterRendererWidget::centerSymbolChanged()
222 {
223  mRenderer->setClusterSymbol( mCenterSymbolToolButton->clonedSymbol< QgsMarkerSymbol >() );
224  emit widgetChanged();
225 }
226 
227 void QgsPointClusterRendererWidget::updateRendererFromWidget()
228 {
229  QgsRendererWidget *w = qobject_cast<QgsRendererWidget *>( sender() );
230  if ( !w )
231  return;
232 
233  mRenderer->setEmbeddedRenderer( w->renderer()->clone() );
234  emit widgetChanged();
235 }
236 
237 void QgsPointClusterRendererWidget::setupBlankUi( const QString &layerName )
238 {
239  QGridLayout *layout = new QGridLayout( this );
240  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 );
241  layout->addWidget( label );
242 }
@ 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.
virtual QgsFeatureRenderer * clone() const =0
Create a deep copy of this renderer.
void copyRendererData(QgsFeatureRenderer *destRenderer) const
Clones generic renderer data to another renderer.
Definition: qgsrenderer.cpp:52
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.
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...
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.
QList< QgsUnitTypes::RenderUnit > RenderUnitList
List of render units.
Definition: qgsunittypes.h:240
@ RenderMetersInMapUnits
Meters value as Map units.
Definition: qgsunittypes.h:176
@ RenderPoints
Points (e.g., for font sizes)
Definition: qgsunittypes.h:173
@ RenderPixels
Pixels.
Definition: qgsunittypes.h:171
@ RenderInches
Inches.
Definition: qgsunittypes.h:174
@ RenderMillimeters
Millimeters.
Definition: qgsunittypes.h:169
@ RenderMapUnits
Map units.
Definition: qgsunittypes.h:170
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.