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