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