QGIS API Documentation 3.99.0-Master (2fe06baccd8)
Loading...
Searching...
No Matches
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
17
18#include <memory>
19
20#include "qgis.h"
21#include "qgsapplication.h"
22#include "qgsmesh3daveraging.h"
23#include "qgsmeshlayer.h"
25#include "qgsscreenhelper.h"
26
27#include <QPainter>
28#include <QPixmap>
29#include <QSvgRenderer>
30
31#include "moc_qgsmeshrenderer3daveragingwidget.cpp"
32
34 : QWidget( parent )
35
36{
37 setupUi( this );
38
39 mScreenHelper = new QgsScreenHelper( this );
40
41 connect( mAveragingMethodComboBox, qOverload<int>( &QComboBox::currentIndexChanged ), this, &QgsMeshRenderer3DAveragingWidget::onAveragingMethodChanged );
42
43 // Single Level Average Method (top)
44 connect( mSingleVerticalLayerIndexTopSpinBox, qOverload<int>( &QgsSpinBox::valueChanged ), this, &QgsMeshRenderer3DAveragingWidget::widgetChanged );
45
46 // Single Level Average Method (bottom)
47 connect( mSingleVerticalLayerIndexBottomSpinBox, qOverload<int>( &QgsSpinBox::valueChanged ), this, &QgsMeshRenderer3DAveragingWidget::widgetChanged );
48
49 // Multi Levels Averaging Method (top)
50 connect( mMultiTopVerticalLayerStartIndexSpinBox, qOverload<int>( &QgsSpinBox::valueChanged ), this, &QgsMeshRenderer3DAveragingWidget::widgetChanged );
51 connect( mMultiTopVerticalLayerEndIndexSpinBox, qOverload<int>( &QgsSpinBox::valueChanged ), this, &QgsMeshRenderer3DAveragingWidget::widgetChanged );
52
53 // MultiLevels Averaging Method (bottom)
54 connect( mMultiBottomVerticalLayerStartIndexSpinBox, qOverload<int>( &QgsSpinBox::valueChanged ), this, &QgsMeshRenderer3DAveragingWidget::widgetChanged );
55 connect( mMultiBottomVerticalLayerEndIndexSpinBox, qOverload<int>( &QgsSpinBox::valueChanged ), this, &QgsMeshRenderer3DAveragingWidget::widgetChanged );
56
57 // Sigma Averaging Method
58 connect( mSigmaStartFractionSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ), this, &QgsMeshRenderer3DAveragingWidget::widgetChanged );
59 connect( mSigmaEndFractionSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ), this, &QgsMeshRenderer3DAveragingWidget::widgetChanged );
60
61 // Depth Averaging Method
62 connect( mDepthStartSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ), this, &QgsMeshRenderer3DAveragingWidget::widgetChanged );
63 connect( mDepthEndSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ), this, &QgsMeshRenderer3DAveragingWidget::widgetChanged );
64
65 // Height Averaging Method
66 connect( mHeightStartSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ), this, &QgsMeshRenderer3DAveragingWidget::widgetChanged );
67 connect( mHeightEndSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ), this, &QgsMeshRenderer3DAveragingWidget::widgetChanged );
68
69
70 // Elevation Averaging Method
71 connect( mElevationStartSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ), this, &QgsMeshRenderer3DAveragingWidget::widgetChanged );
72 connect( mElevationEndSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ), this, &QgsMeshRenderer3DAveragingWidget::widgetChanged );
73
74 updateGraphics();
75 connect( mScreenHelper, &QgsScreenHelper::screenDpiChanged, this, &QgsMeshRenderer3DAveragingWidget::updateGraphics );
76}
77
79{
80 mMeshLayer = layer;
81}
82
83std::unique_ptr<QgsMesh3DAveragingMethod> QgsMeshRenderer3DAveragingWidget::averagingMethod() const
84{
85 std::unique_ptr<QgsMesh3DAveragingMethod> averaging;
86
87 switch ( mAveragingMethodComboBox->currentIndex() )
88 {
89 case 0: // single level from top
90 {
91 const int verticalLevel = mSingleVerticalLayerIndexTopSpinBox->value();
92 averaging = std::make_unique<QgsMeshMultiLevelsAveragingMethod>( verticalLevel, true );
93 break;
94 }
95 case 1: // single level from bottom
96 {
97 const int verticalLevel = mSingleVerticalLayerIndexBottomSpinBox->value();
98 averaging = std::make_unique<QgsMeshMultiLevelsAveragingMethod>( verticalLevel, false );
99 break;
100 }
101 case 2: // multi level from top
102 {
103 const int startVerticalLevel = mMultiTopVerticalLayerStartIndexSpinBox->value();
104 const int endVerticalLevel = mMultiTopVerticalLayerEndIndexSpinBox->value();
105 averaging = std::make_unique<QgsMeshMultiLevelsAveragingMethod>( startVerticalLevel, endVerticalLevel, true );
106 break;
107 }
108 case 3: // multi level from bottom
109 {
110 const int startVerticalLevel = mMultiBottomVerticalLayerStartIndexSpinBox->value();
111 const int endVerticalLevel = mMultiBottomVerticalLayerEndIndexSpinBox->value();
112 averaging = std::make_unique<QgsMeshMultiLevelsAveragingMethod>( startVerticalLevel, endVerticalLevel, false );
113 break;
114 }
115 case 4: // sigma
116 {
117 const double startFraction = mSigmaStartFractionSpinBox->value();
118 const double endFraction = mSigmaEndFractionSpinBox->value();
119 averaging = std::make_unique<QgsMeshSigmaAveragingMethod>( startFraction, endFraction );
120 break;
121 }
122 case 5: // depth (from surface)
123 {
124 const double startDepth = mDepthStartSpinBox->value();
125 const double endDepth = mDepthEndSpinBox->value();
126 averaging = std::make_unique<QgsMeshRelativeHeightAveragingMethod>( startDepth, endDepth, true );
127 break;
128 }
129 case 6: // height (from bed elevation)
130 {
131 const double startHeight = mHeightStartSpinBox->value();
132 const double endHeight = mHeightEndSpinBox->value();
133 averaging = std::make_unique<QgsMeshRelativeHeightAveragingMethod>( startHeight, endHeight, false );
134 break;
135 }
136 case 7: // elevation
137 {
138 const double startVerticalLevel = mElevationStartSpinBox->value();
139 const double endVerticalLevel = mElevationEndSpinBox->value();
140 averaging = std::make_unique<QgsMeshElevationAveragingMethod>( startVerticalLevel, endVerticalLevel );
141 break;
142 }
143 }
144 return averaging;
145}
146
148{
149 if ( !mMeshLayer )
150 return;
151
152 const QgsMeshRendererSettings rendererSettings = mMeshLayer->rendererSettings();
153 const QgsMesh3DAveragingMethod *method = rendererSettings.averagingMethod();
154 if ( method )
155 {
156 const QgsMesh3DAveragingMethod::Method type = method->method();
157 int pageIndex = 0;
158
159 switch ( type )
160 {
162 {
164 if ( averagingMethod->isSingleLevel() )
165 {
166 if ( averagingMethod->countedFromTop() )
167 {
168 // Single Vertical Layer settings from top
169 whileBlocking( mSingleVerticalLayerIndexTopSpinBox )->setValue( averagingMethod->startVerticalLevel() );
170 pageIndex = 0;
171 }
172 else
173 {
174 // Single Vertical Layer settings from bottom
175 whileBlocking( mSingleVerticalLayerIndexBottomSpinBox )->setValue( averagingMethod->startVerticalLevel() );
176 pageIndex = 1;
177 }
178 }
179 else
180 {
181 if ( averagingMethod->countedFromTop() )
182 {
183 // Multi Vertical Layer settings from top
184 whileBlocking( mMultiTopVerticalLayerStartIndexSpinBox )->setValue( averagingMethod->startVerticalLevel() );
185 whileBlocking( mMultiTopVerticalLayerEndIndexSpinBox )->setValue( averagingMethod->endVerticalLevel() );
186 pageIndex = 2;
187 }
188 else
189 {
190 // Multi Vertical Layer settings from bottom
191 whileBlocking( mMultiBottomVerticalLayerStartIndexSpinBox )->setValue( averagingMethod->startVerticalLevel() );
192 whileBlocking( mMultiBottomVerticalLayerEndIndexSpinBox )->setValue( averagingMethod->endVerticalLevel() );
193 pageIndex = 3;
194 }
195 }
196 break;
197 }
199 {
200 const QgsMeshSigmaAveragingMethod *sigmaAveragingMethod = static_cast<const QgsMeshSigmaAveragingMethod *>( method );
201 whileBlocking( mSigmaStartFractionSpinBox )->setValue( sigmaAveragingMethod->startFraction() );
202 whileBlocking( mSigmaEndFractionSpinBox )->setValue( sigmaAveragingMethod->endFraction() );
203 pageIndex = 4;
204 break;
205 }
207 {
209 if ( averagingMethod->countedFromTop() )
210 {
211 whileBlocking( mDepthStartSpinBox )->setValue( averagingMethod->startHeight() );
212 whileBlocking( mDepthEndSpinBox )->setValue( averagingMethod->endHeight() );
213 pageIndex = 5;
214 }
215 else
216 {
217 whileBlocking( mHeightStartSpinBox )->setValue( averagingMethod->startHeight() );
218 whileBlocking( mHeightEndSpinBox )->setValue( averagingMethod->endHeight() );
219 pageIndex = 6;
220 }
221 break;
222 }
224 {
225 const QgsMeshElevationAveragingMethod *elevationAveragingMethod = static_cast<const QgsMeshElevationAveragingMethod *>( method );
226 whileBlocking( mElevationStartSpinBox )->setValue( elevationAveragingMethod->startElevation() );
227 whileBlocking( mElevationEndSpinBox )->setValue( elevationAveragingMethod->endElevation() );
228 pageIndex = 7;
229 break;
230 }
231 }
232 whileBlocking( mAveragingMethodComboBox )->setCurrentIndex( pageIndex );
233 whileBlocking( mAveragingMethodStackedWidget )->setCurrentIndex( pageIndex );
234 }
235}
236
237void QgsMeshRenderer3DAveragingWidget::onAveragingMethodChanged( int methodIndex )
238{
239 whileBlocking( mAveragingMethodStackedWidget )->setCurrentIndex( methodIndex );
240 emit widgetChanged();
241}
242
243void QgsMeshRenderer3DAveragingWidget::updateGraphics()
244{
245 setLabelSvg( mSingleTopPngLabel, QStringLiteral( "SingleTop.svg" ) );
246 mSingleTopGroup->adjustSize();
247
248 setLabelSvg( mSingleBottomPngLabel, QStringLiteral( "SingleBottom.svg" ) );
249 setLabelSvg( mMultiTopPngLabel, QStringLiteral( "MultiTop.svg" ) );
250 setLabelSvg( mMultiBottomPngLabel, QStringLiteral( "MultiBottom.svg" ) );
251 setLabelSvg( mSigmaPngLabel, QStringLiteral( "Sigma.svg" ) );
252 setLabelSvg( mDepthPngLabel, QStringLiteral( "Depth.svg" ) );
253 setLabelSvg( mHeightPngLabel, QStringLiteral( "Height.svg" ) );
254 setLabelSvg( mElevationPngLabel, QStringLiteral( "Elevation.svg" ) );
255}
256
257void QgsMeshRenderer3DAveragingWidget::setLabelSvg( QLabel *imageLabel, const QString &imgName )
258{
259 const qreal dpi = mScreenHelper->screenDpi();
260 const int desiredWidth = static_cast<int>( 100 * dpi / 25.4 );
261
262 QSvgRenderer renderer( QStringLiteral( ":/images/themes/default/mesh/%1" ).arg( imgName ) );
263 if ( renderer.isValid() )
264 {
265 const QSize defaultSvgSize = renderer.defaultSize();
266 const int desiredHeight = defaultSvgSize.height() * desiredWidth / defaultSvgSize.width();
267
268 QPixmap pixmap( QSize( desiredWidth, desiredHeight ) );
269 pixmap.fill( Qt::transparent );
270 QPainter painter;
271
272 painter.begin( &pixmap );
273 renderer.render( &painter );
274 painter.end();
275 imageLabel->setPixmap( pixmap );
276 }
277}
Abstract class for interpolating 3d stacked mesh data to 2d data.
Method method() const
Returns type of averaging method.
Method
Type of averaging method.
@ RelativeHeightAveragingMethod
Method to average values defined by range of relative length units to the surface or bed level.
@ MultiLevelsAveragingMethod
Method to average values from selected vertical layers.
@ ElevationAveragingMethod
Method to average values defined by range of absolute length units to the model's datum.
@ SigmaAveragingMethod
Method to average values between 0 (bed level) and 1 (surface).
Elevation averaging method averages the values based on range defined absolute value to the model's d...
double startElevation() const
Returns start elevation.
double endElevation() const
Returns end elevation.
Represents a mesh layer supporting display of data on structured or unstructured meshes.
Multi level averaging method specifies limits of vertical layers from the top layer down or reversed.
Relative height averaging method which averages the values based on range defined relative to bed ele...
void setLayer(QgsMeshLayer *layer)
Associates mesh layer with the widget.
QgsMeshRenderer3DAveragingWidget(QWidget *parent=nullptr)
A widget to hold the renderer Vector settings for a mesh layer.
void widgetChanged()
Mesh rendering settings changed.
std::unique_ptr< QgsMesh3DAveragingMethod > averagingMethod() const
Returns selected averaging method.
void syncToLayer()
Synchronizes widgets state with associated mesh layer.
Represents all mesh renderer settings.
QgsMesh3DAveragingMethod * averagingMethod() const
Returns averaging method for conversion of 3d stacked mesh data to 2d data.
Sigma averages over the values between 0 (bed level) and 1 (surface).
double endFraction() const
Returns ending fraction.
double startFraction() const
Returns starting fraction.
A utility class for dynamic handling of changes to screen properties.
void screenDpiChanged(double dpi)
Emitted whenever the screen dpi associated with the widget is changed.
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition qgis.h:6511