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