OGS
NetCdfConfigureDialog.cpp
Go to the documentation of this file.
1
11
12#include <vtkImageImport.h>
13
14#include <QMessageBox>
15#include <QSettings>
16
17#include "GeoLib/Raster.h"
18#include "MathLib/Point3d.h"
19#include "MeshLib/MeshEnums.h"
22#include "VtkVis/VtkRaster.h"
23
24using namespace netCDF;
25
26// Constructor
28 QDialog* parent)
29 : QDialog(parent),
30 _currentFile(fileName.c_str(), NcFile::read),
31 _currentMesh(nullptr),
32 _currentRaster(nullptr),
33 _currentPath(fileName)
34{
35 setupUi(this);
36
37 int const idx =
38 setVariableSelect(); // set up variables of the file in the combobox
39 comboBoxVariable->setCurrentIndex(
40 idx); // pre-select the variable with the biggest number of
41 // dimensions...valueWithMaxDim()
43 _currentFile.getVar(comboBoxVariable->itemText(idx).toStdString());
44
46
47 lineEditName->setText(setName());
48
49 this->radioMesh->setChecked(true);
50}
51
53
54// Instructions if the OK-Button has been pressed.
56{
57 QMessageBox valueErrorBox;
58 if (_currentVar.getDimCount() < 2)
59 {
60 valueErrorBox.setText("Selected Variable has not enough dimensions.");
61 valueErrorBox.exec();
62 }
63 else if (doubleSpinBoxDim2Start->value() ==
64 doubleSpinBoxDim2Start->maximum())
65 {
66 valueErrorBox.setText("Lon has invalid extend.");
67 valueErrorBox.exec();
68 }
69 else if (doubleSpinBoxDim1Start->value() ==
70 doubleSpinBoxDim1Start->maximum())
71 {
72 valueErrorBox.setText("Lat has invalid extend.");
73 valueErrorBox.exec();
74 }
75 else
76 {
78 this->done(QDialog::Accepted);
79 }
80}
81
82// Instructions if the Cancel-Button has been pressed.
84{
85 this->done(QDialog::Rejected);
86}
87
89{
90 std::string const var_name = comboBoxVariable->currentText().toStdString();
91 _currentVar = _currentFile.getVar(var_name);
93}
94
95// set up x-axis/lat
97{
98 double firstValue = 0, lastValue = 0;
99 unsigned size = 0;
100 getDimEdges(comboBoxDim1->currentText().toStdString(), size, firstValue,
101 lastValue);
102 doubleSpinBoxDim1Start->setValue(firstValue);
103 doubleSpinBoxDim1End->setValue(lastValue);
104 doubleSpinBoxResolution->setValue(getResolution());
105}
106
107// set up y-axis/lon
109{
110 if (_currentVar.getDimCount() > 1)
111 {
112 double firstValue = 0, lastValue = 0;
113 unsigned size = 0;
114 getDimEdges(comboBoxDim2->currentText().toStdString(), size, firstValue,
115 lastValue);
116 doubleSpinBoxDim2Start->setValue(firstValue);
117 doubleSpinBoxDim2End->setValue(lastValue);
118 }
119}
120
121// set up time
123{
124 if (_currentVar.getDimCount() > 2)
125 {
126 double firstValue = 0, lastValue = 0;
127 unsigned size = 0;
128 getDimEdges(comboBoxDim3->currentText().toStdString(), size, firstValue,
129 lastValue);
130 dateTimeEditDim3->setValue(static_cast<int>(firstValue));
131 dateTimeEditDim3->setMinimum(static_cast<int>(firstValue));
132 dateTimeEditDim3->setMaximum(static_cast<int>(lastValue));
133 lineEditName->setText(setName());
134 }
135}
136
137// set up additional dimension
139{
140 if (_currentVar.getDimCount() > 3)
141 {
142 double firstValue = 0, lastValue = 0;
143 unsigned size = 0;
144 getDimEdges(comboBoxDim4->currentText().toStdString(), size, firstValue,
145 lastValue);
146 spinBoxDim4->setValue(static_cast<int>(firstValue));
147 spinBoxDim4->setMinimum(static_cast<int>(firstValue));
148 spinBoxDim4->setMaximum(static_cast<int>(lastValue));
149 }
150}
151
153{
154 int max_dim = 0;
155 int max_dim_idx = 0;
156 auto const& names = _currentFile.getVars();
157 for (auto [name, var] : names)
158 {
159 int const var_dim_count = var.getDimCount();
160 if (var_dim_count > 1)
161 {
162 comboBoxVariable->addItem(QString::fromStdString(name));
163 if (var_dim_count > max_dim)
164 {
165 max_dim = var_dim_count;
166 max_dim_idx = comboBoxVariable->count() - 1;
167 }
168 }
169 }
170 return max_dim_idx;
171}
172
174{
175 int const dim_count = _currentVar.getDimCount();
176 std::array<QComboBox*, 4> dim_box = {
177 {comboBoxDim1, comboBoxDim2, comboBoxDim3, comboBoxDim4}};
178
179 for (int i = 0; i < 4; ++i)
180 {
181 dim_box[i]->clear();
182 dim_box[i]->setEnabled(i < dim_count);
183 }
184
185 // write dimension-names into selection-boxes
186 for (int i = 0; i < dim_count; ++i)
187 {
188 for (int j = 0; j < dim_count; ++j)
189 {
190 dim_box[j]->addItem(
191 QString::fromStdString(_currentVar.getDim(i).getName()));
192 }
193 }
194 comboBoxDim1->setCurrentIndex(dim_count - 2);
196 comboBoxDim2->setCurrentIndex(dim_count - 1);
198 // time is only enabled if dim > 2
199 dateTimeEditDim3->setEnabled(dim_count > 2);
200 // 3rd data dimension is only enabled if dim > 3
201 spinBoxDim4->setEnabled(dim_count > 3);
202
203 if (dim_count > 2)
204 {
205 comboBoxDim3->setCurrentIndex(0);
207 }
208 else
209 dateTimeEditDim3->setSingleStep(0);
210
211 if (dim_count == 4)
212 {
213 comboBoxDim4->setCurrentIndex(1);
215 }
216 else
217 spinBoxDim4->setValue(0);
218}
219
220void NetCdfConfigureDialog::getDimEdges(std::string const& name, unsigned& size,
221 double& firstValue, double& lastValue)
222{
223 size = 0;
224 firstValue = 0;
225 lastValue = 0;
226 if (_currentFile.getVar(name).isNull())
227 return;
228
229 NcVar const& tmpVarOfDim = _currentFile.getVar(name);
230 if ((tmpVarOfDim.getDimCount()) == 1)
231 {
232 size = tmpVarOfDim.getDim(0).getSize();
233 tmpVarOfDim.getVar({0}, {1}, &firstValue);
234 tmpVarOfDim.getVar({size - 1}, {1}, &lastValue);
235 }
236}
237
239{
240 return dateTimeEditDim3->value();
241}
242
244{
245 NcVar const& dim3Var =
246 _currentFile.getVar(comboBoxDim4->currentText().toStdString());
247 std::vector<std::size_t> start{
248 static_cast<std::size_t>(spinBoxDim4->value())};
249 int value(0);
250 dim3Var.getVar(start, {1}, &value);
251 if (value < 0)
252 value = 0; // if the value isn't found in the array, set it to 0 as
253 // default...
254 return value;
255}
256
258{
259 if (comboBoxDim1->currentIndex() > -1)
260 {
261 NcVar const& var =
262 _currentFile.getVar(comboBoxDim1->currentText().toStdString());
263 double firstValue = 0, lastValue = 0;
264 unsigned size = 0;
265 getDimEdges(var.getName(), size, firstValue, lastValue);
266 if (size < 2)
267 {
268 return 1;
269 }
270
271 double interval = fabs(lastValue - firstValue);
272 double resolution = (double)interval / (size - 1);
273 return resolution;
274 }
275
276 return 0;
277}
278
280{
281 double originLon = 0, originLat = 0;
282 double lastLon = 0, lastLat = 0;
283 unsigned sizeLon = 0, sizeLat = 0;
284 std::string const dim1_name = comboBoxDim1->currentText().toStdString();
285 getDimEdges(dim1_name, sizeLat, originLat, lastLat);
286 std::string const dim2_name = comboBoxDim2->currentText().toStdString();
287 getDimEdges(dim2_name, sizeLon, originLon, lastLon);
288
289 // set up array
290 std::vector<double> data_array(sizeLat * sizeLon, 0);
291
292 std::vector<std::size_t> data_origin;
293 std::vector<std::size_t> data_length;
294
295 if (_currentVar.getDimCount() > 2)
296 {
297 // time
298 data_origin.push_back(getTimeStep());
299 data_length.push_back(1);
300 // 3rd dimension
301 if (_currentVar.getDimCount() > 3)
302 {
303 data_origin.push_back(getDim4());
304 data_length.push_back(1);
305 }
306 }
307
308 data_origin.push_back(0); // x-origin
309 data_origin.push_back(0); // y-origin
310 data_length.push_back(sizeLat);
311 data_length.push_back(sizeLon);
312 _currentVar.getVar(data_origin, data_length, data_array.data());
313
314 std::replace_if(
315 data_array.begin(), data_array.end(),
316 [](double const& x) { return x <= -9999; }, -9999);
317
318 double origin_x = (originLon < lastLon) ? originLon : lastLon;
319 double origin_y = (originLat < lastLat) ? originLat : lastLat;
320 MathLib::Point3d origin(std::array<double, 3>{{origin_x, origin_y, 0}});
321 double resolution = (doubleSpinBoxResolution->value());
322
323 if (originLat >
324 lastLat) // reverse lines in vertical direction if the original file
325 // has its origin in the northwest corner
326 this->reverseNorthSouth(data_array.data(), sizeLon, sizeLat);
327
328 GeoLib::RasterHeader const header = {sizeLon, sizeLat, 1,
329 origin, resolution, -9999};
330 if (this->radioMesh->isChecked())
331 {
333 MeshLib::UseIntensityAs useIntensity =
335 if (comboBoxMeshElemType->currentIndex() == 1)
336 {
337 meshElemType = MeshLib::MeshElemType::TRIANGLE;
338 }
339 else
340 {
341 meshElemType = MeshLib::MeshElemType::QUAD;
342 }
343 if ((comboBoxUseIntensity->currentIndex()) == 1)
344 {
346 }
347 else
348 {
350 }
352 data_array.data(), header, meshElemType, useIntensity,
353 _currentVar.getName());
354 }
355 else
356 {
357 vtkImageImport* image =
358 VtkRaster::loadImageFromArray(data_array.data(), header);
361 QString::fromStdString(this->getName()));
362 }
363}
364
366{
367 std::string name;
368 name.append(_currentPath);
369 name.erase(0, name.find_last_of("/") + 1);
370 name.erase(name.find_last_of("."));
371 return QString::fromStdString(name);
372}
373
375{
376 std::string name = (lineEditName->text()).toStdString();
377 QString const date = QString::number(dateTimeEditDim3->value());
378 name.append(" - ").append(date.toStdString());
379 return name;
380}
381
382void NetCdfConfigureDialog::reverseNorthSouth(double* data, std::size_t width,
383 std::size_t height)
384{
385 auto* cp_array = new double[width * height];
386
387 for (std::size_t i = 0; i < height; i++)
388 {
389 for (std::size_t j = 0; j < width; j++)
390 {
391 std::size_t old_index((width * height) - (width * (i + 1)));
392 std::size_t new_index(width * i);
393 cp_array[new_index + j] = data[old_index + j];
394 }
395 }
396
397 std::size_t length(height * width);
398 for (std::size_t i = 0; i < length; i++)
399 data[i] = cp_array[i];
400
401 delete[] cp_array;
402}
403
405{
406 if (isTrue) // output set to "mesh"
407 {
408 this->label_2->setEnabled(true);
409 this->label_3->setEnabled(false);
410 this->comboBoxMeshElemType->setEnabled(true);
411 this->comboBoxUseIntensity->setEnabled(false);
412 }
413 else // output set to "raster"
414 {
415 this->label_2->setEnabled(false);
416 this->label_3->setEnabled(true);
417 this->comboBoxMeshElemType->setEnabled(false);
418 this->comboBoxUseIntensity->setEnabled(true);
419 }
420}
Definition of mesh-related Enumerations.
Definition of the Point3d class.
Definition of the GeoLib::Raster class.
Definition of the VtkGeoImageSource class.
Definition of the VtkRaster class.
static std::unique_ptr< MeshLib::Mesh > convert(GeoLib::Raster const &raster, MeshElemType elem_type, UseIntensityAs intensity_type, std::string const &array_name="Colour")
VtkGeoImageSource * _currentRaster
void on_comboBoxDim3_currentIndexChanged(int id)
void on_radioMesh_toggled(bool isTrue)
std::unique_ptr< MeshLib::Mesh > _currentMesh
void on_comboBoxVariable_currentIndexChanged(int id)
void reverseNorthSouth(double *data, std::size_t width, std::size_t height)
void on_comboBoxDim1_currentIndexChanged(int id)
NetCdfConfigureDialog(const std::string &fileName, QDialog *parent=nullptr)
void on_comboBoxDim2_currentIndexChanged(int id)
~NetCdfConfigureDialog() override
void getDimEdges(std::string const &name, unsigned &size, double &firstValue, double &lastValue)
void on_comboBoxDim4_currentIndexChanged(int id)
void setImage(vtkImageAlgorithm *image, const QString &name)
Imports an existing image object.
static VtkGeoImageSource * New()
Create new objects with New() because of VTKs reference counting.
static vtkImageImport * loadImageFromArray(double const *const data_array, GeoLib::RasterHeader header)
Returns a VtkImageAlgorithm from an array of pixel values and some image meta data.
Definition: VtkRaster.cpp:82
UseIntensityAs
Selection of possible interpretations for intensities.
Definition: MeshEnums.h:83
MeshElemType
Types of mesh elements supported by OpenGeoSys. Values are from VTKCellType enum.
Definition: MeshEnums.h:27
Contains the relevant information when storing a geoscientific raster data.
Definition: Raster.h:27