QGIS API Documentation 3.99.0-Master (e9821da5c6b)
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 <QString>
30#include <QSvgRenderer>
31
32#include "moc_qgsmeshrenderer3daveragingwidget.cpp"
33
34using namespace Qt::StringLiterals;
35
37 : QWidget( parent )
38
39{
40 setupUi( this );
41
42 mScreenHelper = new QgsScreenHelper( this );
43
44 connect( mAveragingMethodComboBox, qOverload<int>( &QComboBox::currentIndexChanged ), this, &QgsMeshRenderer3DAveragingWidget::onAveragingMethodChanged );
45
46 // Single Level Average Method (top)
47 connect( mSingleVerticalLayerIndexTopSpinBox, qOverload<int>( &QgsSpinBox::valueChanged ), this, &QgsMeshRenderer3DAveragingWidget::widgetChanged );
48
49 // Single Level Average Method (bottom)
50 connect( mSingleVerticalLayerIndexBottomSpinBox, qOverload<int>( &QgsSpinBox::valueChanged ), this, &QgsMeshRenderer3DAveragingWidget::widgetChanged );
51
52 // Multi Levels Averaging Method (top)
53 connect( mMultiTopVerticalLayerStartIndexSpinBox, qOverload<int>( &QgsSpinBox::valueChanged ), this, &QgsMeshRenderer3DAveragingWidget::widgetChanged );
54 connect( mMultiTopVerticalLayerEndIndexSpinBox, qOverload<int>( &QgsSpinBox::valueChanged ), this, &QgsMeshRenderer3DAveragingWidget::widgetChanged );
55
56 // MultiLevels Averaging Method (bottom)
57 connect( mMultiBottomVerticalLayerStartIndexSpinBox, qOverload<int>( &QgsSpinBox::valueChanged ), this, &QgsMeshRenderer3DAveragingWidget::widgetChanged );
58 connect( mMultiBottomVerticalLayerEndIndexSpinBox, qOverload<int>( &QgsSpinBox::valueChanged ), this, &QgsMeshRenderer3DAveragingWidget::widgetChanged );
59
60 // Sigma Averaging Method
61 connect( mSigmaStartFractionSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ), this, &QgsMeshRenderer3DAveragingWidget::widgetChanged );
62 connect( mSigmaEndFractionSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ), this, &QgsMeshRenderer3DAveragingWidget::widgetChanged );
63
64 // Depth Averaging Method
65 connect( mDepthStartSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ), this, &QgsMeshRenderer3DAveragingWidget::widgetChanged );
66 connect( mDepthEndSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ), this, &QgsMeshRenderer3DAveragingWidget::widgetChanged );
67
68 // Height Averaging Method
69 connect( mHeightStartSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ), this, &QgsMeshRenderer3DAveragingWidget::widgetChanged );
70 connect( mHeightEndSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ), this, &QgsMeshRenderer3DAveragingWidget::widgetChanged );
71
72
73 // Elevation Averaging Method
74 connect( mElevationStartSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ), this, &QgsMeshRenderer3DAveragingWidget::widgetChanged );
75 connect( mElevationEndSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ), this, &QgsMeshRenderer3DAveragingWidget::widgetChanged );
76
77 updateGraphics();
78 connect( mScreenHelper, &QgsScreenHelper::screenDpiChanged, this, &QgsMeshRenderer3DAveragingWidget::updateGraphics );
79}
80
82{
83 mMeshLayer = layer;
84}
85
86std::unique_ptr<QgsMesh3DAveragingMethod> QgsMeshRenderer3DAveragingWidget::averagingMethod() const
87{
88 std::unique_ptr<QgsMesh3DAveragingMethod> averaging;
89
90 switch ( mAveragingMethodComboBox->currentIndex() )
91 {
92 case 0: // single level from top
93 {
94 const int verticalLevel = mSingleVerticalLayerIndexTopSpinBox->value();
95 averaging = std::make_unique<QgsMeshMultiLevelsAveragingMethod>( verticalLevel, true );
96 break;
97 }
98 case 1: // single level from bottom
99 {
100 const int verticalLevel = mSingleVerticalLayerIndexBottomSpinBox->value();
101 averaging = std::make_unique<QgsMeshMultiLevelsAveragingMethod>( verticalLevel, false );
102 break;
103 }
104 case 2: // multi level from top
105 {
106 const int startVerticalLevel = mMultiTopVerticalLayerStartIndexSpinBox->value();
107 const int endVerticalLevel = mMultiTopVerticalLayerEndIndexSpinBox->value();
108 averaging = std::make_unique<QgsMeshMultiLevelsAveragingMethod>( startVerticalLevel, endVerticalLevel, true );
109 break;
110 }
111 case 3: // multi level from bottom
112 {
113 const int startVerticalLevel = mMultiBottomVerticalLayerStartIndexSpinBox->value();
114 const int endVerticalLevel = mMultiBottomVerticalLayerEndIndexSpinBox->value();
115 averaging = std::make_unique<QgsMeshMultiLevelsAveragingMethod>( startVerticalLevel, endVerticalLevel, false );
116 break;
117 }
118 case 4: // sigma
119 {
120 const double startFraction = mSigmaStartFractionSpinBox->value();
121 const double endFraction = mSigmaEndFractionSpinBox->value();
122 averaging = std::make_unique<QgsMeshSigmaAveragingMethod>( startFraction, endFraction );
123 break;
124 }
125 case 5: // depth (from surface)
126 {
127 const double startDepth = mDepthStartSpinBox->value();
128 const double endDepth = mDepthEndSpinBox->value();
129 averaging = std::make_unique<QgsMeshRelativeHeightAveragingMethod>( startDepth, endDepth, true );
130 break;
131 }
132 case 6: // height (from bed elevation)
133 {
134 const double startHeight = mHeightStartSpinBox->value();
135 const double endHeight = mHeightEndSpinBox->value();
136 averaging = std::make_unique<QgsMeshRelativeHeightAveragingMethod>( startHeight, endHeight, false );
137 break;
138 }
139 case 7: // elevation
140 {
141 const double startVerticalLevel = mElevationStartSpinBox->value();
142 const double endVerticalLevel = mElevationEndSpinBox->value();
143 averaging = std::make_unique<QgsMeshElevationAveragingMethod>( startVerticalLevel, endVerticalLevel );
144 break;
145 }
146 }
147 return averaging;
148}
149
151{
152 if ( !mMeshLayer )
153 return;
154
155 const QgsMeshRendererSettings rendererSettings = mMeshLayer->rendererSettings();
156 const QgsMesh3DAveragingMethod *method = rendererSettings.averagingMethod();
157 if ( method )
158 {
159 const QgsMesh3DAveragingMethod::Method type = method->method();
160 int pageIndex = 0;
161
162 switch ( type )
163 {
165 {
167 if ( averagingMethod->isSingleLevel() )
168 {
169 if ( averagingMethod->countedFromTop() )
170 {
171 // Single Vertical Layer settings from top
172 whileBlocking( mSingleVerticalLayerIndexTopSpinBox )->setValue( averagingMethod->startVerticalLevel() );
173 pageIndex = 0;
174 }
175 else
176 {
177 // Single Vertical Layer settings from bottom
178 whileBlocking( mSingleVerticalLayerIndexBottomSpinBox )->setValue( averagingMethod->startVerticalLevel() );
179 pageIndex = 1;
180 }
181 }
182 else
183 {
184 if ( averagingMethod->countedFromTop() )
185 {
186 // Multi Vertical Layer settings from top
187 whileBlocking( mMultiTopVerticalLayerStartIndexSpinBox )->setValue( averagingMethod->startVerticalLevel() );
188 whileBlocking( mMultiTopVerticalLayerEndIndexSpinBox )->setValue( averagingMethod->endVerticalLevel() );
189 pageIndex = 2;
190 }
191 else
192 {
193 // Multi Vertical Layer settings from bottom
194 whileBlocking( mMultiBottomVerticalLayerStartIndexSpinBox )->setValue( averagingMethod->startVerticalLevel() );
195 whileBlocking( mMultiBottomVerticalLayerEndIndexSpinBox )->setValue( averagingMethod->endVerticalLevel() );
196 pageIndex = 3;
197 }
198 }
199 break;
200 }
202 {
203 const QgsMeshSigmaAveragingMethod *sigmaAveragingMethod = static_cast<const QgsMeshSigmaAveragingMethod *>( method );
204 whileBlocking( mSigmaStartFractionSpinBox )->setValue( sigmaAveragingMethod->startFraction() );
205 whileBlocking( mSigmaEndFractionSpinBox )->setValue( sigmaAveragingMethod->endFraction() );
206 pageIndex = 4;
207 break;
208 }
210 {
212 if ( averagingMethod->countedFromTop() )
213 {
214 whileBlocking( mDepthStartSpinBox )->setValue( averagingMethod->startHeight() );
215 whileBlocking( mDepthEndSpinBox )->setValue( averagingMethod->endHeight() );
216 pageIndex = 5;
217 }
218 else
219 {
220 whileBlocking( mHeightStartSpinBox )->setValue( averagingMethod->startHeight() );
221 whileBlocking( mHeightEndSpinBox )->setValue( averagingMethod->endHeight() );
222 pageIndex = 6;
223 }
224 break;
225 }
227 {
228 const QgsMeshElevationAveragingMethod *elevationAveragingMethod = static_cast<const QgsMeshElevationAveragingMethod *>( method );
229 whileBlocking( mElevationStartSpinBox )->setValue( elevationAveragingMethod->startElevation() );
230 whileBlocking( mElevationEndSpinBox )->setValue( elevationAveragingMethod->endElevation() );
231 pageIndex = 7;
232 break;
233 }
234 }
235 whileBlocking( mAveragingMethodComboBox )->setCurrentIndex( pageIndex );
236 whileBlocking( mAveragingMethodStackedWidget )->setCurrentIndex( pageIndex );
237 }
238}
239
240void QgsMeshRenderer3DAveragingWidget::onAveragingMethodChanged( int methodIndex )
241{
242 whileBlocking( mAveragingMethodStackedWidget )->setCurrentIndex( methodIndex );
243 emit widgetChanged();
244}
245
246void QgsMeshRenderer3DAveragingWidget::updateGraphics()
247{
248 setLabelSvg( mSingleTopPngLabel, u"SingleTop.svg"_s );
249 mSingleTopGroup->adjustSize();
250
251 setLabelSvg( mSingleBottomPngLabel, u"SingleBottom.svg"_s );
252 setLabelSvg( mMultiTopPngLabel, u"MultiTop.svg"_s );
253 setLabelSvg( mMultiBottomPngLabel, u"MultiBottom.svg"_s );
254 setLabelSvg( mSigmaPngLabel, u"Sigma.svg"_s );
255 setLabelSvg( mDepthPngLabel, u"Depth.svg"_s );
256 setLabelSvg( mHeightPngLabel, u"Height.svg"_s );
257 setLabelSvg( mElevationPngLabel, u"Elevation.svg"_s );
258}
259
260void QgsMeshRenderer3DAveragingWidget::setLabelSvg( QLabel *imageLabel, const QString &imgName )
261{
262 const qreal dpi = mScreenHelper->screenDpi();
263 const int desiredWidth = static_cast<int>( 100 * dpi / 25.4 );
264
265 QSvgRenderer renderer( u":/images/themes/default/mesh/%1"_s.arg( imgName ) );
266 if ( renderer.isValid() )
267 {
268 const QSize defaultSvgSize = renderer.defaultSize();
269 const int desiredHeight = defaultSvgSize.height() * desiredWidth / defaultSvgSize.width();
270
271 QPixmap pixmap( QSize( desiredWidth, desiredHeight ) );
272 pixmap.fill( Qt::transparent );
273 QPainter painter;
274
275 painter.begin( &pixmap );
276 renderer.render( &painter );
277 painter.end();
278 imageLabel->setPixmap( pixmap );
279 }
280}
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:6828