From b8893c46215e980147786164ca42b6468d2e4fec Mon Sep 17 00:00:00 2001
From: rinkk <karsten.rink@ufz.de>
Date: Mon, 2 Sep 2019 16:41:55 +0200
Subject: [PATCH] adjusted code to work with netcdf-cxx4 library

---
 .../NetCdfDialog/NetCdfConfigure.ui           |  66 +----
 .../NetCdfDialog/NetCdfConfigureDialog.cpp    | 229 ++++++------------
 .../NetCdfDialog/NetCdfConfigureDialog.h      |  11 +-
 3 files changed, 86 insertions(+), 220 deletions(-)

diff --git a/Applications/DataExplorer/NetCdfDialog/NetCdfConfigure.ui b/Applications/DataExplorer/NetCdfDialog/NetCdfConfigure.ui
index 6bcd090175f..523cf2193ea 100644
--- a/Applications/DataExplorer/NetCdfDialog/NetCdfConfigure.ui
+++ b/Applications/DataExplorer/NetCdfDialog/NetCdfConfigure.ui
@@ -167,68 +167,6 @@
         </property>
        </widget>
       </item>
-      <item row="0" column="2">
-       <widget class="QDateTimeEdit" name="dateTimeEditDim3">
-        <property name="minimumSize">
-         <size>
-          <width>110</width>
-          <height>0</height>
-         </size>
-        </property>
-        <property name="maximumSize">
-         <size>
-          <width>110</width>
-          <height>16777215</height>
-         </size>
-        </property>
-        <property name="autoFillBackground">
-         <bool>false</bool>
-        </property>
-        <property name="dateTime">
-         <datetime>
-          <hour>0</hour>
-          <minute>0</minute>
-          <second>0</second>
-          <year>1900</year>
-          <month>1</month>
-          <day>1</day>
-         </datetime>
-        </property>
-        <property name="date">
-         <date>
-          <year>1900</year>
-          <month>1</month>
-          <day>1</day>
-         </date>
-        </property>
-        <property name="maximumDateTime">
-         <datetime>
-          <hour>23</hour>
-          <minute>59</minute>
-          <second>59</second>
-          <year>2200</year>
-          <month>12</month>
-          <day>31</day>
-         </datetime>
-        </property>
-        <property name="minimumDateTime">
-         <datetime>
-          <hour>0</hour>
-          <minute>0</minute>
-          <second>0</second>
-          <year>1900</year>
-          <month>1</month>
-          <day>1</day>
-         </datetime>
-        </property>
-        <property name="displayFormat">
-         <string>dd.MM.yyyy</string>
-        </property>
-        <property name="calendarPopup">
-         <bool>true</bool>
-        </property>
-       </widget>
-      </item>
       <item row="3" column="3">
        <spacer name="horizontalSpacer_8">
         <property name="orientation">
@@ -255,6 +193,9 @@
         </property>
        </spacer>
       </item>
+      <item row="0" column="2">
+       <widget class="QSpinBox" name="dateTimeEditDim3"/>
+      </item>
      </layout>
     </widget>
    </item>
@@ -720,7 +661,6 @@
   <tabstop>doubleSpinBoxDim2Start</tabstop>
   <tabstop>doubleSpinBoxDim2End</tabstop>
   <tabstop>comboBoxDim3</tabstop>
-  <tabstop>dateTimeEditDim3</tabstop>
   <tabstop>comboBoxDim4</tabstop>
   <tabstop>spinBoxDim4</tabstop>
   <tabstop>doubleSpinBoxResolution</tabstop>
diff --git a/Applications/DataExplorer/NetCdfDialog/NetCdfConfigureDialog.cpp b/Applications/DataExplorer/NetCdfDialog/NetCdfConfigureDialog.cpp
index 49fd033f722..68c248f1100 100644
--- a/Applications/DataExplorer/NetCdfDialog/NetCdfConfigureDialog.cpp
+++ b/Applications/DataExplorer/NetCdfDialog/NetCdfConfigureDialog.cpp
@@ -25,8 +25,11 @@ using namespace netCDF;
 
 // Constructor
 NetCdfConfigureDialog::NetCdfConfigureDialog(std::string const& fileName, QDialog* parent)
-    : QDialog(parent), _currentFile(fileName.c_str(), NcFile::read),
-  _currentInitialDateTime(QDateTime()), _currentMesh(nullptr), _currentRaster(nullptr), _currentPath(fileName)
+    : QDialog(parent),
+      _currentFile(fileName.c_str(), NcFile::read),
+      _currentMesh(nullptr),
+      _currentRaster(nullptr),
+      _currentPath(fileName)
 {
     setupUi(this);
 
@@ -70,7 +73,7 @@ void NetCdfConfigureDialog::reject()
 
 void NetCdfConfigureDialog::on_comboBoxVariable_currentIndexChanged(int id)
 {
-    std::string const var_name = comboBoxVariable->itemText(_id_map[id]).toStdString();
+    std::string const var_name = comboBoxVariable->currentText().toStdString();
     _currentVar = _currentFile.getVar(var_name);
     setDimensionSelect();
 }
@@ -81,7 +84,7 @@ void NetCdfConfigureDialog::on_comboBoxDim1_currentIndexChanged(int id)
     if (id == -1) id = 0;
     double firstValue=0, lastValue=0;
     unsigned size = 0;
-    getDimEdges(id,size,firstValue,lastValue);
+    getDimEdges(comboBoxDim1->currentText().toStdString(), size, firstValue, lastValue);
     doubleSpinBoxDim1Start->setValue(firstValue);
     doubleSpinBoxDim1End->setValue(lastValue);
     doubleSpinBoxResolution->setValue(getResolution());
@@ -95,7 +98,7 @@ void NetCdfConfigureDialog::on_comboBoxDim2_currentIndexChanged(int id)
         if (id == -1) id = 0;
         double firstValue=0, lastValue=0;
         unsigned size = 0;
-        getDimEdges(id,size,firstValue,lastValue);
+        getDimEdges(comboBoxDim2->currentText().toStdString(), size, firstValue, lastValue);
         doubleSpinBoxDim2Start->setValue(firstValue);
         doubleSpinBoxDim2End->setValue(lastValue);
     }
@@ -109,32 +112,10 @@ void NetCdfConfigureDialog::on_comboBoxDim3_currentIndexChanged(int id)
         if (id == -1) id = 0;
         double firstValue=0, lastValue=0;
         unsigned size = 0;
-        getDimEdges(id,size,firstValue,lastValue);
-
-        QTime firstTime(0,0,0), lastTime(0,0,0);
-        int firstDaysToAdd = 0, lastDaysToAdd = 0;
-
-        getDaysTime(firstValue,firstTime,firstDaysToAdd);
-        getDaysTime(lastValue,lastTime,lastDaysToAdd);
-
-        QDate initialDate(1960,1,1);
-        QTime initialTime(0,0);
-
-        QDateTime initialDateTime;
-        initialDateTime.setDate(initialDate);
-        initialDateTime.setTime(initialTime);
-
-        QDateTime firstDateTime = initialDateTime.addDays(firstDaysToAdd);
-        firstDateTime.setTime(firstTime);
-
-        QDateTime lastDateTime = initialDateTime.addDays(lastDaysToAdd);
-        lastDateTime.setTime(lastTime);
-
-        dateTimeEditDim3->setDateTime(firstDateTime);
-        dateTimeEditDim3->setMinimumDateTime(firstDateTime);
-        dateTimeEditDim3->setMaximumDateTime(lastDateTime);
-
-        _currentInitialDateTime = initialDateTime;
+        getDimEdges(comboBoxDim3->currentText().toStdString(), size, firstValue, lastValue);
+        dateTimeEditDim3->setValue(static_cast<int>(firstValue));
+        dateTimeEditDim3->setMinimum(static_cast<int>(firstValue));
+        dateTimeEditDim3->setMaximum(static_cast<int>(lastValue));
         lineEditName->setText(setName());
     }
 }
@@ -144,11 +125,9 @@ void NetCdfConfigureDialog::on_comboBoxDim4_currentIndexChanged(int id)
 {
     if (_currentVar.getDimCount() > 3)
     {
-        if (id == -1) id = 0;
         double firstValue=0, lastValue=0;
         unsigned size = 0;
-        getDimEdges(id,size,firstValue,lastValue);
-        // WARNING: Implicit conversion to int in spinBoxDim4->set*()
+        getDimEdges(comboBoxDim4->currentText().toStdString(), size, firstValue, lastValue);
         spinBoxDim4->setValue(static_cast<int>(firstValue));
         spinBoxDim4->setMinimum(static_cast<int>(firstValue));
         spinBoxDim4->setMaximum(static_cast<int>(lastValue));
@@ -160,15 +139,11 @@ int NetCdfConfigureDialog::setVariableSelect()
     int max_dim = 0;
     int max_dim_idx = 0;
     auto const& names =_currentFile.getVars();
-    //auto const n_vars = _currentFile.getVarCount();
-    //for (int i = 0; i < n_vars; i++)
     for (auto it = names.cbegin(); it != names.cend(); ++it)
     {
-        //NcVar const& focusedVar = _currentFile.getVar(i);
         int const var_dim_count = it->second.getDimCount();
         if (var_dim_count > 1)
         {
-            //_id_map.push_back(i);
             comboBoxVariable->addItem(QString::fromStdString(it->first));
             if (var_dim_count > max_dim)
             {
@@ -182,36 +157,41 @@ int NetCdfConfigureDialog::setVariableSelect()
 
 void NetCdfConfigureDialog::setDimensionSelect()
 {
-    int const dim = _currentVar.getDimCount();
+    int const dim_count = _currentVar.getDimCount();
     std::array<QComboBox*,4> dim_box = {{ comboBoxDim1, comboBoxDim2, comboBoxDim3, comboBoxDim4 }};
 
     for (int i = 0; i < 4; ++i)
     {
         dim_box[i]->clear();
-        dim_box[i]->setEnabled(i < dim);
+        dim_box[i]->setEnabled(i < dim_count);
     }
 
-    for (int i=0; i < dim; ++i) //write dimension-names into selection-boxes
+    // write dimension-names into selection-boxes
+    for (int i = 0; i < dim_count; ++i)
     {
-        for (int j = 0; j < dim; ++j)
+        for (int j = 0; j < dim_count; ++j)
+        {
             dim_box[j]->addItem(QString::fromStdString(_currentVar.getDim(i).getName()));
+        }
     }
-    comboBoxDim1->setCurrentIndex(dim-2);
-    on_comboBoxDim1_currentIndexChanged(dim-2);
-    comboBoxDim2->setCurrentIndex(dim-1);
-    on_comboBoxDim2_currentIndexChanged(dim-1);
-    dateTimeEditDim3->setEnabled(dim > 2); // time is only enabled if dim > 2
-    spinBoxDim4->setEnabled(dim > 3); // add. info is only enabled if dim > 3
-
-    if (dim > 2)
+    comboBoxDim1->setCurrentIndex(dim_count - 2);
+    on_comboBoxDim1_currentIndexChanged(dim_count - 2);
+    comboBoxDim2->setCurrentIndex(dim_count - 1);
+    on_comboBoxDim2_currentIndexChanged(dim_count - 1);
+    // time is only enabled if dim > 2
+    dateTimeEditDim3->setEnabled(dim_count > 2);
+    // 3rd data dimension is only enabled if dim > 3
+    spinBoxDim4->setEnabled(dim_count > 3);
+
+    if (dim_count > 2)
     {
         comboBoxDim3->setCurrentIndex(0);
         on_comboBoxDim3_currentIndexChanged(0);
     }
     else
-        dateTimeEditDim3->setDateTime(_currentInitialDateTime);
+        dateTimeEditDim3->setSingleStep(0);
 
-    if (dim == 4)
+    if (dim_count == 4)
     {
         comboBoxDim4->setCurrentIndex(1);
         on_comboBoxDim4_currentIndexChanged(1);
@@ -220,32 +200,18 @@ void NetCdfConfigureDialog::setDimensionSelect()
         spinBoxDim4->setValue(0);
 }
 
-void NetCdfConfigureDialog::getDimEdges(int dimId, unsigned &size, double &firstValue, double &lastValue)
+void NetCdfConfigureDialog::getDimEdges(std::string const& name, unsigned& size,
+                                        double& firstValue, double& lastValue)
 {
     size = 0;
     firstValue = 0;
     lastValue = 0;
-    if (_currentFile.getVar(_currentVar.getDim(dimId).getName()).isNull())
+    if (_currentFile.getVar(name).isNull())
         return;
 
-    NcVar const& tmpVarOfDim = _currentFile.getVar(_currentVar.getDim(dimId).getName());
+    NcVar const& tmpVarOfDim = _currentFile.getVar(name);
     if ((tmpVarOfDim.getDimCount()) == 1)
     {
-        /*
-        int sizeOfDim = tmpVarOfDim.getDim(0).getSize();
-        size = sizeOfDim;
-        double *arrayOfDimStart = new double[1]; //[1] = {0};
-        long edgeOfArray = 1; //[1] = {1};
-        long edgeOrigin[1] = {0};
-        tmpVarOfDim.set_cur(edgeOrigin);
-        tmpVarOfDim->get(arrayOfDimStart,edgeOfArray);
-        firstValue = arrayOfDimStart[0];
-        double arrayOfDimEnd[1] = {0};
-        edgeOrigin[0] = sizeOfDim - 1;
-        tmpVarOfDim->set_cur(edgeOrigin);
-        tmpVarOfDim->get(arrayOfDimEnd,edgeOfArray);
-        lastValue = arrayOfDimEnd[0];
-        */
         size = tmpVarOfDim.getDim(0).getSize();
         std::vector<std::size_t> start_val{{0}};
         std::vector<std::size_t> length{{1}};
@@ -255,65 +221,34 @@ void NetCdfConfigureDialog::getDimEdges(int dimId, unsigned &size, double &first
     }
 }
 
-void NetCdfConfigureDialog::getDaysTime(double minSince, QTime &time, int &days)
+int NetCdfConfigureDialog::getTimeStep() const
 {
-    auto tmpMin = (long)minSince;
-    long minuits = tmpMin % 60;
-    long tmpHours = tmpMin / 60;
-    long hours = tmpHours % 24;
-    days = (int)(tmpHours / 24);
-    time.setHMS(hours, minuits, 0);
-}
-
-long NetCdfConfigureDialog::convertDateToMinutes(QDateTime initialDateTime, QDate selectedDate, QTime selectedTime)
-{
-    long tmpInitialToSelectedDate = static_cast<long>(selectedDate.daysTo(initialDateTime.date()));
-    long selectedDays = - tmpInitialToSelectedDate * 24 * 60;
-    long selectedMinutes = (selectedTime.hour() * 60) + selectedTime.minute() + selectedDays;
-    return selectedMinutes;
-}
-
-int NetCdfConfigureDialog::getTimeStep()
-{
-    NcVar const& timeVar =
-        _currentFile.getVar(comboBoxDim2->currentText().toStdString());
-
-    double const datesToMinutes = convertDateToMinutes(_currentInitialDateTime,dateTimeEditDim3->date(),dateTimeEditDim3->time());
-
-    double timeArray[1] = {datesToMinutes};
-    /*
-    double currentTime = timeVar.get_index(timeArray);
-    if (currentTime < 0) currentTime=0; //if the value isn't found in the array, set it to 0 as default...
-    return static_cast<int>(currentTime);
-    */
-    /** TODO **/
-    return 0;
+    NcVar const& time_var =
+        _currentFile.getVar(comboBoxDim3->currentText().toStdString());
+    return dateTimeEditDim3->value();
 }
 
 int NetCdfConfigureDialog::getDim4() const
 {
-    /** TODO **/
-    /*
     NcVar const& dim3Var =
         _currentFile.getVar(comboBoxDim4->currentText().toStdString());
-    int timeArray[1] = {spinBoxDim4->value()};
-    int currentValueDim3 = dim3Var.get_index(timeArray);
-    if (currentValueDim3 < 0)
-        currentValueDim3=0; //if the value isn't found in the array, set it to 0 as default...
-    return currentValueDim3;
-    */
-    return 0;
+    std::vector<std::size_t> start{{static_cast<std::size_t>(spinBoxDim4->value())}};
+    std::vector<std::size_t> length{{1}};
+    int value(0);
+    dim3Var.getVar(start, length, &value);
+    if (value < 0)
+        value = 0; //if the value isn't found in the array, set it to 0 as default...
+    return value;
 }
 
 double NetCdfConfigureDialog::getResolution()
 {
     if (comboBoxDim1->currentIndex() > -1)
     {
-        NcVar const& latVar =
-            _currentFile.getVar(comboBoxDim1->currentText().toStdString());
+        NcVar const& var = _currentFile.getVar(comboBoxDim1->currentText().toStdString());
         double firstValue = 0, lastValue = 0;
         unsigned size = 0;
-        getDimEdges(latVar.getId(), size, firstValue, lastValue);
+        getDimEdges(var.getName(), size, firstValue, lastValue);
         if (size < 2)
         {
             return 1;
@@ -329,46 +264,41 @@ double NetCdfConfigureDialog::getResolution()
 
 void NetCdfConfigureDialog::createDataObject()
 {
-    auto* length = new std::size_t[_currentVar.getDimCount()];
     double originLon = 0, originLat = 0;
     double lastLon = 0, lastLat = 0;
     unsigned sizeLon = 0, sizeLat = 0;
-    getDimEdges(comboBoxDim1->currentIndex(), sizeLat, originLat, lastLat);
-    getDimEdges(comboBoxDim2->currentIndex(), sizeLon, originLon, lastLon);
-
-
-    for(int i=0; i < _currentVar.getDimCount(); i++) length[i]=1;
-
-    // set array edges: lat x lon
-    length[comboBoxDim1->currentIndex()]=sizeLat;
-    length[comboBoxDim2->currentIndex()]=sizeLon;
+    std::string const dim1_name = comboBoxDim1->currentText().toStdString();
+    getDimEdges(dim1_name, sizeLat, originLat, lastLat);
+    std::string const dim2_name = comboBoxDim2->currentText().toStdString();
+    getDimEdges(dim2_name, sizeLon, originLon, lastLon);
 
     // set up array
-    auto* data_array = new double[sizeLat * sizeLon];
-    for(std::size_t i=0; i < (sizeLat*sizeLon); i++) data_array[i]=0;
+    std::vector<double> data_array(sizeLat * sizeLon, 0);
+
+    std::vector<std::size_t> data_origin;
+    std::vector<std::size_t> data_length;
 
-    //Time-Dimension:
-    /*
     if (_currentVar.getDimCount() > 2)
     {
-        auto* newOrigin = new long[_currentVar.getDimCount()];
-        for (int i=0; i < _currentVar.getDimCount(); i++) newOrigin[i]=0;
-        newOrigin[comboBoxDim3->currentIndex()] = getTimeStep(); //set origin to selected time
-        _currentVar.set_cur(newOrigin);
-        //Dimension 4:
-        if (_currentVar.getDimCount() > 3) newOrigin[comboBoxDim4->currentIndex()] = getDim4(); //if there are is a 4th dimension
-        delete [] newOrigin;
+        // time
+        data_origin.push_back(getTimeStep());
+        data_length.push_back(1);
+        // 3rd dimension
+        if (_currentVar.getDimCount() > 3)
+        {
+            data_origin.push_back(getDim4());
+            data_length.push_back(1);
+        }
     }
-    */
-    std::vector<std::size_t> data_origin {{0, 0}};
-    std::vector<std::size_t> data_length {{sizeLat, sizeLon}};
-    _currentVar.getVar(data_origin, data_length, data_array);  // create Array of Values
 
-    for (std::size_t i=0; i < (sizeLat*sizeLon); i++)
-    {
-        //data_array[i] = data_array[i] - 273; // convert from kalvin to celsius
-        if (data_array[i] < -9999 ) data_array[i] = -9999; // all values < -10000, set to "no-value"
-    }
+    data_origin.push_back(0); // x-origin
+    data_origin.push_back(0); // y-origin
+    data_length.push_back(sizeLat);
+    data_length.push_back(sizeLon);
+    _currentVar.getVar(data_origin, data_length, data_array.data());
+
+    std::replace_if(data_array.begin(), data_array.end(),
+                    [](double& x) { return x <= -9999; }, -9999);
 
     double origin_x = (originLon < lastLon) ? originLon : lastLon;
     double origin_y = (originLat < lastLat) ? originLat : lastLat;
@@ -376,7 +306,7 @@ void NetCdfConfigureDialog::createDataObject()
     double resolution = (doubleSpinBoxResolution->value());
 
     if (originLat > lastLat) // reverse lines in vertical direction if the original file has its origin in the northwest corner
-        this->reverseNorthSouth(data_array, sizeLon, sizeLat);
+        this->reverseNorthSouth(data_array.data(), sizeLon, sizeLat);
 
     GeoLib::RasterHeader const header = {sizeLon, sizeLat,    1,
                                          origin,  resolution, -9999};
@@ -397,17 +327,14 @@ void NetCdfConfigureDialog::createDataObject()
             useIntensity = MeshLib::UseIntensityAs::DATAVECTOR;
         }
         _currentMesh = MeshLib::RasterToMesh::convert(
-            data_array, header, meshElemType, useIntensity, _currentVar.getName());
+            data_array.data(), header, meshElemType, useIntensity, _currentVar.getName());
     }
     else
     {
-        vtkImageImport* image = VtkRaster::loadImageFromArray(data_array, header);
+        vtkImageImport* image = VtkRaster::loadImageFromArray(data_array.data(), header);
         _currentRaster = VtkGeoImageSource::New();
         _currentRaster->setImage(image, QString::fromStdString(this->getName()), origin[0], origin[1], resolution);
     }
-
-    delete[] length;
-    delete[] data_array;
 }
 
 QString NetCdfConfigureDialog::setName()
@@ -422,7 +349,7 @@ QString NetCdfConfigureDialog::setName()
 std::string NetCdfConfigureDialog::getName()
 {
     std::string name = (lineEditName->text()).toStdString();
-    QString date = dateTimeEditDim3->date().toString(Qt::LocalDate);
+    QString date = dateTimeEditDim3->value();
     name.append(" - ").append(date.toStdString());
     return name;
 }
diff --git a/Applications/DataExplorer/NetCdfDialog/NetCdfConfigureDialog.h b/Applications/DataExplorer/NetCdfDialog/NetCdfConfigureDialog.h
index 829384c4e85..5a25c141097 100644
--- a/Applications/DataExplorer/NetCdfDialog/NetCdfConfigureDialog.h
+++ b/Applications/DataExplorer/NetCdfDialog/NetCdfConfigureDialog.h
@@ -55,11 +55,12 @@ private:
     /// returns the index of the first variable with the highest dimension.
     int setVariableSelect();
     void setDimensionSelect();
-    void getDimEdges(int dimId, unsigned &size, double &firstValue, double &lastValue);
-    void getDaysTime(double minSince, QTime &time, int &days);
-    long convertDateToMinutes(QDateTime initialDateTime,QDate selectedDate, QTime selectedTime);
+    void getDimEdges(std::string const& name,
+                     unsigned& size,
+                     double& firstValue,
+                     double& lastValue);
     void createDataObject();
-    int getTimeStep();
+    int getTimeStep() const;
     int getDim4() const;
     double getResolution();
     QString setName();
@@ -67,9 +68,7 @@ private:
 
     netCDF::NcFile _currentFile;
     netCDF::NcVar _currentVar;
-    QDateTime _currentInitialDateTime;
     MeshLib::Mesh* _currentMesh;
     VtkGeoImageSource* _currentRaster;
     std::string _currentPath;
-    std::vector<int> _id_map;
 };
-- 
GitLab