QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
qgsmeshrenderer3daveragingwidget.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsmeshrenderer3daveragingwidget.cpp
3  ------------------------------------
4  begin : November 2019
5  copyright : (C) 2019 by Peter Petrik
6  email : zilolv at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #include <memory>
17 #include <QSvgRenderer>
18 #include <QPainter>
19 #include <QScreen>
20 #include <QPixmap>
21 #include <QDesktopWidget>
22 
24 
25 #include "qgis.h"
26 #include "qgsmeshlayer.h"
27 #include "qgsmessagelog.h"
29 #include "qgsmesh3daveraging.h"
30 #include "qgsapplication.h"
31 
32 static void _setSvg( QLabel *imageLabel,
33  const QString &imgName )
34 {
35  const qreal dpi = QgsApplication::desktop()->logicalDpiX();
36  const int desiredWidth = static_cast<int>( 100 * dpi / 25.4 );
37 
38  QSvgRenderer renderer( QStringLiteral( ":/images/themes/default/mesh/%1" ).arg( imgName ) );
39  if ( renderer.isValid() )
40  {
41  const QSize defaultSvgSize = renderer.defaultSize();
42  const int desiredHeight = defaultSvgSize.height() * desiredWidth / defaultSvgSize.width();
43 
44  QPixmap pixmap( QSize( desiredWidth, desiredHeight ) );
45  pixmap.fill( Qt::transparent );
46  QPainter painter;
47 
48  painter.begin( &pixmap );
49  renderer.render( &painter );
50  painter.end();
51  imageLabel->setPixmap( pixmap );
52  }
53 }
54 
56  : QWidget( parent )
57 
58 {
59  setupUi( this );
60  connect( mAveragingMethodComboBox, qOverload<int>( &QComboBox::currentIndexChanged ),
61  this, &QgsMeshRenderer3dAveragingWidget::onAveragingMethodChanged );
62 
63  // Single Level Average Method (top)
64  connect( mSingleVerticalLayerIndexTopSpinBox, qOverload<int>( &QgsSpinBox::valueChanged ),
66  _setSvg( mSingleTopPngLabel,
67  QStringLiteral( "SingleTop.svg" )
68  );
69  mSingleTopGroup->adjustSize();
70 
71  // Single Level Average Method (bottom)
72  connect( mSingleVerticalLayerIndexBottomSpinBox, qOverload<int>( &QgsSpinBox::valueChanged ),
74  _setSvg( mSingleBottomPngLabel,
75  QStringLiteral( "SingleBottom.svg" )
76  );
77 
78  // Multi Levels Averaging Method (top)
79  connect( mMultiTopVerticalLayerStartIndexSpinBox, qOverload<int>( &QgsSpinBox::valueChanged ),
81  connect( mMultiTopVerticalLayerEndIndexSpinBox, qOverload<int>( &QgsSpinBox::valueChanged ),
83  _setSvg( mMultiTopPngLabel,
84  QStringLiteral( "MultiTop.svg" )
85  );
86 
87  // MultiLevels Averaging Method (bottom)
88  connect( mMultiBottomVerticalLayerStartIndexSpinBox, qOverload<int>( &QgsSpinBox::valueChanged ),
90  connect( mMultiBottomVerticalLayerEndIndexSpinBox, qOverload<int>( &QgsSpinBox::valueChanged ),
92  _setSvg( mMultiBottomPngLabel,
93  QStringLiteral( "MultiBottom.svg" )
94  );
95 
96  // Sigma Averaging Method
97  connect( mSigmaStartFractionSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ),
99  connect( mSigmaEndFractionSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ),
101  _setSvg( mSigmaPngLabel,
102  QStringLiteral( "Sigma.svg" )
103  );
104 
105  // Depth Averaging Method
106  connect( mDepthStartSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ),
108  connect( mDepthEndSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ),
110  _setSvg( mDepthPngLabel,
111  QStringLiteral( "Depth.svg" )
112  );
113 
114  // Height Averaging Method
115  connect( mHeightStartSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ),
117  connect( mHeightEndSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ),
119  _setSvg( mHeightPngLabel,
120  QStringLiteral( "Height.svg" )
121  );
122 
123  // Elevation Averaging Method
124  connect( mElevationStartSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ),
126  connect( mElevationEndSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ),
128  _setSvg( mElevationPngLabel,
129  QStringLiteral( "Elevation.svg" )
130  );
131 }
132 
134 {
135  mMeshLayer = layer;
136 }
137 
138 std::unique_ptr<QgsMesh3dAveragingMethod> QgsMeshRenderer3dAveragingWidget::averagingMethod() const
139 {
140  std::unique_ptr<QgsMesh3dAveragingMethod> averaging;
141 
142  switch ( mAveragingMethodComboBox->currentIndex() )
143  {
144  case 0: // single level from top
145  {
146  const int verticalLevel = mSingleVerticalLayerIndexTopSpinBox->value();
147  averaging.reset( new QgsMeshMultiLevelsAveragingMethod( verticalLevel, true ) );
148  break;
149  }
150  case 1: // single level from bottom
151  {
152  const int verticalLevel = mSingleVerticalLayerIndexBottomSpinBox->value();
153  averaging.reset( new QgsMeshMultiLevelsAveragingMethod( verticalLevel, false ) );
154  break;
155  }
156  case 2: // multi level from top
157  {
158  const int startVerticalLevel = mMultiTopVerticalLayerStartIndexSpinBox->value();
159  const int endVerticalLevel = mMultiTopVerticalLayerEndIndexSpinBox->value();
160  averaging.reset( new QgsMeshMultiLevelsAveragingMethod( startVerticalLevel, endVerticalLevel, true ) );
161  break;
162  }
163  case 3: // multi level from bottom
164  {
165  const int startVerticalLevel = mMultiBottomVerticalLayerStartIndexSpinBox->value();
166  const int endVerticalLevel = mMultiBottomVerticalLayerEndIndexSpinBox->value();
167  averaging.reset( new QgsMeshMultiLevelsAveragingMethod( startVerticalLevel, endVerticalLevel, false ) );
168  break;
169  }
170  case 4: // sigma
171  {
172  const double startFraction = mSigmaStartFractionSpinBox->value();
173  const double endFraction = mSigmaEndFractionSpinBox->value();
174  averaging.reset( new QgsMeshSigmaAveragingMethod( startFraction, endFraction ) );
175  break;
176  }
177  case 5: // depth (from surface)
178  {
179  const double startDepth = mDepthStartSpinBox->value();
180  const double endDepth = mDepthEndSpinBox->value();
181  averaging.reset( new QgsMeshRelativeHeightAveragingMethod( startDepth, endDepth, true ) );
182  break;
183  }
184  case 6: // height (from bed elevation)
185  {
186  const double startHeight = mHeightStartSpinBox->value();
187  const double endHeight = mHeightEndSpinBox->value();
188  averaging.reset( new QgsMeshRelativeHeightAveragingMethod( startHeight, endHeight, false ) );
189  break;
190  }
191  case 7: // elevation
192  {
193  const double startVerticalLevel = mElevationStartSpinBox->value();
194  const double endVerticalLevel = mElevationEndSpinBox->value();
195  averaging.reset( new QgsMeshElevationAveragingMethod( startVerticalLevel, endVerticalLevel ) );
196  break;
197  }
198  }
199  return averaging;
200 }
201 
203 {
204  if ( !mMeshLayer )
205  return;
206 
207  const QgsMeshRendererSettings rendererSettings = mMeshLayer->rendererSettings();
208  const QgsMesh3dAveragingMethod *method = rendererSettings.averagingMethod();
209  if ( method )
210  {
211  const QgsMesh3dAveragingMethod::Method type = method->method();
212  int pageIndex = 0;
213 
214  switch ( type )
215  {
217  {
219  if ( averagingMethod->isSingleLevel() )
220  {
221  if ( averagingMethod->countedFromTop() )
222  {
223  // Single Vertical Layer settings from top
224  whileBlocking( mSingleVerticalLayerIndexTopSpinBox )->setValue( averagingMethod->startVerticalLevel() );
225  pageIndex = 0;
226  }
227  else
228  {
229  // Single Vertical Layer settings from bottom
230  whileBlocking( mSingleVerticalLayerIndexBottomSpinBox )->setValue( averagingMethod->startVerticalLevel() );
231  pageIndex = 1;
232  }
233  }
234  else
235  {
236  if ( averagingMethod->countedFromTop() )
237  {
238  // Multi Vertical Layer settings from top
239  whileBlocking( mMultiTopVerticalLayerStartIndexSpinBox )->setValue( averagingMethod->startVerticalLevel() );
240  whileBlocking( mMultiTopVerticalLayerEndIndexSpinBox )->setValue( averagingMethod->endVerticalLevel() );
241  pageIndex = 2;
242  }
243  else
244  {
245  // Multi Vertical Layer settings from bottom
246  whileBlocking( mMultiBottomVerticalLayerStartIndexSpinBox )->setValue( averagingMethod->startVerticalLevel() );
247  whileBlocking( mMultiBottomVerticalLayerEndIndexSpinBox )->setValue( averagingMethod->endVerticalLevel() );
248  pageIndex = 3;
249  }
250  }
251  break;
252  }
254  {
255  const QgsMeshSigmaAveragingMethod *sigmaAveragingMethod = static_cast<const QgsMeshSigmaAveragingMethod *>( method );
256  whileBlocking( mSigmaStartFractionSpinBox )->setValue( sigmaAveragingMethod->startFraction() );
257  whileBlocking( mSigmaEndFractionSpinBox )->setValue( sigmaAveragingMethod->endFraction() );
258  pageIndex = 4;
259  break;
260  }
262  {
264  if ( averagingMethod->countedFromTop() )
265  {
266  whileBlocking( mDepthStartSpinBox )->setValue( averagingMethod->startHeight() );
267  whileBlocking( mDepthEndSpinBox )->setValue( averagingMethod->endHeight() );
268  pageIndex = 5;
269  }
270  else
271  {
272  whileBlocking( mHeightStartSpinBox )->setValue( averagingMethod->startHeight() );
273  whileBlocking( mHeightEndSpinBox )->setValue( averagingMethod->endHeight() );
274  pageIndex = 6;
275  }
276  break;
277  }
279  {
280  const QgsMeshElevationAveragingMethod *elevationAveragingMethod = static_cast<const QgsMeshElevationAveragingMethod *>( method );
281  whileBlocking( mElevationStartSpinBox )->setValue( elevationAveragingMethod->startElevation() );
282  whileBlocking( mElevationEndSpinBox )->setValue( elevationAveragingMethod->endElevation() );
283  pageIndex = 7;
284  break;
285  }
286  }
287  whileBlocking( mAveragingMethodComboBox )->setCurrentIndex( pageIndex );
288  whileBlocking( mAveragingMethodStackedWidget )->setCurrentIndex( pageIndex );
289  }
290 }
291 
292 void QgsMeshRenderer3dAveragingWidget::onAveragingMethodChanged( int methodIndex )
293 {
294  whileBlocking( mAveragingMethodStackedWidget )->setCurrentIndex( methodIndex );
295  emit widgetChanged();
296 }
qgsmesh3daveraging.h
QgsMesh3dAveragingMethod::RelativeHeightAveragingMethod
@ RelativeHeightAveragingMethod
Method to average values defined by range of relative length units to the surface or bed level.
Definition: qgsmesh3daveraging.h:81
QgsMeshRendererSettings
Represents all mesh renderer settings.
Definition: qgsmeshrenderersettings.h:590
QgsMesh3dAveragingMethod::Method
Method
Type of averaging method.
Definition: qgsmesh3daveraging.h:74
QgsMesh3dAveragingMethod::SigmaAveragingMethod
@ SigmaAveragingMethod
Method to average values between 0 (bed level) and 1 (surface)
Definition: qgsmesh3daveraging.h:79
QgsMeshMultiLevelsAveragingMethod
Multi level averaging method specifies limits of vertical layers from the top layer down or reversed.
Definition: qgsmesh3daveraging.h:158
qgis.h
QgsMesh3dAveragingMethod::method
Method method() const
Returns type of averaging method.
Definition: qgsmesh3daveraging.cpp:137
QgsMeshSigmaAveragingMethod::startFraction
double startFraction() const
Returns starting fraction.
Definition: qgsmesh3daveraging.cpp:406
QgsMeshSigmaAveragingMethod
Sigma averages over the values between 0 (bed level) and 1 (surface).
Definition: qgsmesh3daveraging.h:238
QgsMeshElevationAveragingMethod
Elevation averaging method averages the values based on range defined absolute value to the model's d...
Definition: qgsmesh3daveraging.h:361
qgsapplication.h
QgsMeshRenderer3dAveragingWidget::averagingMethod
std::unique_ptr< QgsMesh3dAveragingMethod > averagingMethod() const
Returns selected averaging method.
Definition: qgsmeshrenderer3daveragingwidget.cpp:138
QgsMeshLayer::rendererSettings
QgsMeshRendererSettings rendererSettings() const
Returns renderer settings.
Definition: qgsmeshlayer.cpp:344
whileBlocking
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition: qgis.h:2191
QgsMeshRelativeHeightAveragingMethod
Relative height averaging method averages the values based on range defined relative to bed elevation...
Definition: qgsmesh3daveraging.h:299
QgsMeshLayer
Represents a mesh layer supporting display of data on structured or unstructured meshes.
Definition: qgsmeshlayer.h:98
QgsMesh3dAveragingMethod::MultiLevelsAveragingMethod
@ MultiLevelsAveragingMethod
Method to average values from selected vertical layers.
Definition: qgsmesh3daveraging.h:77
QgsMeshElevationAveragingMethod::startElevation
double startElevation() const
Returns start elevation.
Definition: qgsmesh3daveraging.cpp:605
qgsmeshrenderer3daveragingwidget.h
QgsMesh3dAveragingMethod
Abstract class to interpolate 3d stacked mesh data to 2d data.
Definition: qgsmesh3daveraging.h:39
qgsmeshlayer.h
qgsmeshrenderersettings.h
QgsMeshRendererSettings::averagingMethod
QgsMesh3dAveragingMethod * averagingMethod() const
Returns averaging method for conversion of 3d stacked mesh data to 2d data.
Definition: qgsmeshrenderersettings.cpp:394
QgsMeshRenderer3dAveragingWidget::QgsMeshRenderer3dAveragingWidget
QgsMeshRenderer3dAveragingWidget(QWidget *parent=nullptr)
A widget to hold the renderer Vector settings for a mesh layer.
Definition: qgsmeshrenderer3daveragingwidget.cpp:55
QgsMeshSigmaAveragingMethod::endFraction
double endFraction() const
Returns ending fraction.
Definition: qgsmesh3daveraging.cpp:411
QgsMeshRenderer3dAveragingWidget::widgetChanged
void widgetChanged()
Mesh rendering settings changed.
QgsMeshElevationAveragingMethod::endElevation
double endElevation() const
Returns end elevation.
Definition: qgsmesh3daveraging.cpp:610
QgsMeshRenderer3dAveragingWidget::syncToLayer
void syncToLayer()
Synchronizes widgets state with associated mesh layer.
Definition: qgsmeshrenderer3daveragingwidget.cpp:202
QgsMeshRenderer3dAveragingWidget::setLayer
void setLayer(QgsMeshLayer *layer)
Associates mesh layer with the widget.
Definition: qgsmeshrenderer3daveragingwidget.cpp:133
QgsMesh3dAveragingMethod::ElevationAveragingMethod
@ ElevationAveragingMethod
Method to average values defined by range of absolute length units to the model's datum.
Definition: qgsmesh3daveraging.h:83
qgsmessagelog.h