diff --git a/agrolib/dbMeteoGrid/dbMeteoGrid.cpp b/agrolib/dbMeteoGrid/dbMeteoGrid.cpp index b06d3439c..602b34b58 100644 --- a/agrolib/dbMeteoGrid/dbMeteoGrid.cpp +++ b/agrolib/dbMeteoGrid/dbMeteoGrid.cpp @@ -1789,6 +1789,101 @@ bool Crit3DMeteoGridDbHandler::loadGridDailyData(QString &myError, const QString return true; } +bool Crit3DMeteoGridDbHandler::loadGridDailyMeteoPrec(QString &myError, const QString &meteoPointId, const QDate &firstDate, const QDate &lastDate) +{ + myError = ""; + QString tableD = _tableDaily.prefix + meteoPointId + _tableDaily.postFix; + + unsigned row, col; + if ( !_meteoGrid->findMeteoPointFromId(&row, &col, meteoPointId.toStdString()) ) + { + myError = "Missing meteoPoint id: " + meteoPointId; + return false; + } + + int numberOfDays = firstDate.daysTo(lastDate) + 1; + _meteoGrid->meteoPointPointer(row, col)->initializeObsDataD(numberOfDays, getCrit3DDate(firstDate)); + + if (_firstDailyDate.isValid() && _lastDailyDate.isValid()) + { + if (_firstDailyDate.year() != 1800 && _lastDailyDate.year() != 1800) + { + if (firstDate > _lastDailyDate || lastDate < _firstDailyDate) + { + myError = "Missing data in this time interval."; + return false; + } + } + } + + QSqlQuery qry(_db); + QString statement; + bool isSingleDate = false; + QDate date; + + QList varList; + varList.push_back(QString::number(getDailyVarCode(dailyAirTemperatureMin))); + varList.push_back(QString::number(getDailyVarCode(dailyAirTemperatureMax))); + varList.push_back(QString::number(getDailyVarCode(dailyAirTemperatureAvg))); + varList.push_back(QString::number(getDailyVarCode(dailyPrecipitation))); + + + if (firstDate == lastDate) + { + statement = QString("SELECT * FROM `%1` WHERE %2 = '%3' AND `VariableCode` IN ('%4')") + .arg(tableD, _tableDaily.fieldTime, firstDate.toString("yyyy-MM-dd"), varList.join("','")); + isSingleDate = true; + date = firstDate; + } + else + { + statement = QString("SELECT * FROM `%1` WHERE %2 >= '%3' AND %2 <= '%4' AND `VariableCode` IN ('%5') ORDER BY %2") + .arg(tableD, _tableDaily.fieldTime, firstDate.toString("yyyy-MM-dd"), lastDate.toString("yyyy-MM-dd"), varList.join("','")); + } + qry.prepare(statement); + + if(! qry.exec()) + { + myError = qry.lastError().text(); + return false; + } + + int varCode; + float value; + while (qry.next()) + { + getValue(qry.value("Value"), &value); + + if (value != NODATA) + { + if (! isSingleDate) + { + if (! getValue(qry.value(_tableDaily.fieldTime), &date)) + { + myError = "Missing " + _tableDaily.fieldTime; + return false; + } + } + + if (! getValue(qry.value("VariableCode"), &varCode)) + { + myError = "Missing VariableCode"; + return false; + } + + meteoVariable variable = getDailyVarEnum(varCode); + + if (! _meteoGrid->meteoPointPointer(row, col)->setMeteoPointValueD(getCrit3DDate(date), variable, value)) + { + myError = "Error in setMeteoPointValueD"; + return false; + } + } + } + + return true; +} + bool Crit3DMeteoGridDbHandler::loadGridDailyDataEnsemble(QString &myError, QString meteoPoint, int memberNr, QDate first, QDate last) { diff --git a/agrolib/dbMeteoGrid/dbMeteoGrid.h b/agrolib/dbMeteoGrid/dbMeteoGrid.h index 949776578..0d72ea8c3 100644 --- a/agrolib/dbMeteoGrid/dbMeteoGrid.h +++ b/agrolib/dbMeteoGrid/dbMeteoGrid.h @@ -115,6 +115,7 @@ bool loadGridDailyData(QString &myError, const QString &meteoPointId, const QDate &firstDate, const QDate &lastDate); bool loadGridDailyDataFixedFields(QString &myError, QString meteoPoint, QDate first, QDate last); bool loadGridDailyDataEnsemble(QString &myError, QString meteoPoint, int memberNr, QDate first, QDate last); + bool loadGridDailyMeteoPrec(QString &myError, const QString &meteoPointId, const QDate &firstDate, const QDate &lastDate); bool loadGridHourlyData(QString &myError, QString meteoPoint, QDateTime firstDate, QDateTime lastDate); bool loadGridHourlyDataFixedFields(QString &myError, QString meteoPoint, QDateTime first, QDateTime last); bool loadGridHourlyDataEnsemble(QString &myError, QString meteoPoint, int memberNr, QDateTime first, QDateTime last); diff --git a/agrolib/dbMeteoPoints/dbMeteoPointsHandler.cpp b/agrolib/dbMeteoPoints/dbMeteoPointsHandler.cpp index 46a492a37..5f02bc484 100644 --- a/agrolib/dbMeteoPoints/dbMeteoPointsHandler.cpp +++ b/agrolib/dbMeteoPoints/dbMeteoPointsHandler.cpp @@ -1888,7 +1888,7 @@ QList Crit3DMeteoPointsDbHandler::getIdListGivenDataset(QList datasetList += "'" + dataset + "'"; } } - QString statement = "SELECT id_point from point_properties WHERE dataset IN (" + datasetList + ")"; + QString statement = "SELECT id_point from point_properties WHERE UPPER(dataset) IN (" + datasetList.toUpper() + ")"; if( !qry.exec(statement) ) { diff --git a/agrolib/dbMeteoPoints/download.cpp b/agrolib/dbMeteoPoints/download.cpp index a6cd9d71e..c0eb5e469 100644 --- a/agrolib/dbMeteoPoints/download.cpp +++ b/agrolib/dbMeteoPoints/download.cpp @@ -140,7 +140,7 @@ QMap Download::getArmiketIdList(QList datasetList) qDebug() << "jsonDataset: value is not string"; else foreach(QString item, _datasetsList) - if (jsonDataset == item) + if (jsonDataset.toString().toUpper() == item.toUpper()) { QString idValue; QString nameValue; diff --git a/agrolib/mathFunctions/furtherMathFunctions.cpp b/agrolib/mathFunctions/furtherMathFunctions.cpp index 5d19e3fd0..574e2cebe 100644 --- a/agrolib/mathFunctions/furtherMathFunctions.cpp +++ b/agrolib/mathFunctions/furtherMathFunctions.cpp @@ -1478,7 +1478,7 @@ namespace interpolation a[counterDim][counterDim] += lambda[i][k]*a[counterDim][counterDim]; for (j = counterDim+1; j < nrParametersTotal; j++) { - a[j][i] = a[i][j]; + a[j][counterDim] = a[counterDim][j]; } counterDim++; } @@ -1664,7 +1664,7 @@ namespace interpolation a[counterDim][counterDim] += lambda[i][k]; for (j = counterDim+1; j < nrParametersTotal; j++) { - a[j][i] = a[i][j]; + a[j][counterDim] = a[counterDim][j]; } counterDim++; } @@ -1803,7 +1803,7 @@ namespace interpolation a[counterDim][counterDim] += lambda[i][k]*a[counterDim][counterDim]; for (j = counterDim+1; j < nrParametersTotal; j++) { - a[j][i] = a[i][j]; + a[j][counterDim] = a[counterDim][j]; } counterDim++; } @@ -2032,7 +2032,7 @@ namespace interpolation a[k][k] += lambda[k]*a[k][k]; for (j = k+1; j < nrParameters; j++) { - a[j][i] = a[i][j]; + a[j][k] = a[k][j]; } } // linear system resolution by matrix inversion diff --git a/agrolib/meteo/meteoPoint.cpp b/agrolib/meteo/meteoPoint.cpp index 3b1771cca..ab3908d16 100644 --- a/agrolib/meteo/meteoPoint.cpp +++ b/agrolib/meteo/meteoPoint.cpp @@ -1007,6 +1007,14 @@ Crit3DDate Crit3DMeteoPoint::getLastDailyData() return obsDataD[nrObsDataDaysD-1].date; } +Crit3DDate Crit3DMeteoPoint::getFirstDailyData() +{ + if (obsDataD.size() == 0) + return NO_DATE; + + return obsDataD[0].date; +} + float Crit3DMeteoPoint::getMeteoPointValueD(const Crit3DDate &myDate, meteoVariable myVar, Crit3DMeteoSettings* meteoSettings) { diff --git a/agrolib/meteo/meteoPoint.h b/agrolib/meteo/meteoPoint.h index d946fe8b6..2c86a6da4 100644 --- a/agrolib/meteo/meteoPoint.h +++ b/agrolib/meteo/meteoPoint.h @@ -148,6 +148,7 @@ void initializeObsDataM(unsigned int numberOfMonths, unsigned int month, int year); bool existDailyData(const Crit3DDate& myDate); + Crit3DDate getFirstDailyData(); Crit3DDate getLastDailyData(); float getMeteoPointValueH(const Crit3DDate& myDate, int myHour, int myMinutes, meteoVariable myVar); diff --git a/agrolib/project/project.cpp b/agrolib/project/project.cpp index dc3c43333..cb370eb43 100644 --- a/agrolib/project/project.cpp +++ b/agrolib/project/project.cpp @@ -4602,14 +4602,15 @@ bool Project::computeSingleWell(QString idWell, int indexWell) { bool isMeteoGridLoaded; QDate firstMeteoDate = wellPoints[indexWell].getFirstDate().addDays(-730); // necessari 24 mesi di dati meteo precedenti il primo dato di falda + double wellUtmX = wellPoints[indexWell].getUtmX(); + double wellUtmY = wellPoints[indexWell].getUtmY(); + Crit3DMeteoPoint linkedMeteoPoint; if (this->meteoGridDbHandler != nullptr) { - loadMeteoGridDailyData(firstMeteoDate, this->meteoGridDbHandler->getLastDailyDate(), true); isMeteoGridLoaded = true; } else if (meteoPoints != nullptr) { - loadMeteoPointsData(firstMeteoDate, this->meteoPointsDbHandler->getLastDate(daily).date(), false, true, true); isMeteoGridLoaded = false; } else @@ -4617,13 +4618,142 @@ bool Project::computeSingleWell(QString idWell, int indexWell) logError(ERROR_STR_MISSING_POINT_GRID); return false; } - + if (!assignNearestMeteoPoint(isMeteoGridLoaded, wellUtmX, wellUtmY, firstMeteoDate, &linkedMeteoPoint)) + { + logError("Missing near weather data"); + return false; + } + if (linkedMeteoPoint.nrObsDataDaysD == 0) + { + logError("Missing near weather data"); + return false; + } int maxNrDays = 730; // attualmente fisso - WaterTable waterTable(meteoPoints, nrMeteoPoints, meteoGridDbHandler->meteoGrid(), isMeteoGridLoaded, *meteoSettings, gisSettings); + WaterTable waterTable(&linkedMeteoPoint, *meteoSettings, gisSettings); waterTable.computeWaterTable(wellPoints[indexWell], maxNrDays); + waterTable.viewWaterTableSeries(); // prepare series to show waterTableList.push_back(waterTable); + return true; +} + +void Project::showSingleWell(WaterTable waterTable, QString idWell) +{ DialogSummary* dialogResult = new DialogSummary(waterTable); // show results - waterTable.viewWaterTableSeries(); // prepare series to show + dialogResult->show(); WaterTableWidget* chartResult = new WaterTableWidget(idWell, waterTable.getMyDates(), waterTable.getMyHindcastSeries(), waterTable.getMyInterpolateSeries(), waterTable.getDepths()); - return true; + chartResult->show(); + return; +} + +bool Project::assignNearestMeteoPoint(bool isMeteoGridLoaded, double wellUtmX, double wellUtmY, QDate firstMeteoDate, Crit3DMeteoPoint* linkedMeteoPoint) +{ + float minimumDistance = NODATA; + bool assignNearestMeteoPoint = false; + if (isMeteoGridLoaded) + { + std::string assignNearestId; + unsigned int assignNearestRow; + unsigned int assignNearestCol; + int zoneNumber; + QDate lastDate = this->meteoGridDbHandler->getLastDailyDate(); + for (unsigned row = 0; row < unsigned(meteoGridDbHandler->meteoGrid()->gridStructure().header().nrRows); row++) + { + for (unsigned col = 0; col < unsigned(meteoGridDbHandler->meteoGrid()->gridStructure().header().nrCols); col++) + { + if (meteoGridDbHandler->meteoGrid()->meteoPointPointer(row,col)->active) + { + double utmX = meteoGridDbHandler->meteoGrid()->meteoPointPointer(row,col)->point.utm.x; + double utmY = meteoGridDbHandler->meteoGrid()->meteoPointPointer(row,col)->point.utm.y; + if (utmX == NODATA || utmY == NODATA) + { + double lat = meteoGridDbHandler->meteoGrid()->meteoPointPointer(row,col)->latitude; + double lon = meteoGridDbHandler->meteoGrid()->meteoPointPointer(row,col)->longitude; + gis::latLonToUtm(lat, lon, &utmX, &utmY, &zoneNumber); + } + float myDistance = gis::computeDistance(wellUtmX, wellUtmY, utmX, utmY); + if (myDistance < MAXWELLDISTANCE ) + { + if (myDistance < minimumDistance || minimumDistance == NODATA) + { + minimumDistance = myDistance; + assignNearestId = meteoGridDbHandler->meteoGrid()->meteoPointPointer(row,col)->id; + assignNearestRow = row; + assignNearestCol = col; + assignNearestMeteoPoint = true; + } + } + } + } + } + if (assignNearestMeteoPoint) + { + meteoGridDbHandler->loadGridDailyMeteoPrec(errorString, QString::fromStdString(assignNearestId), firstMeteoDate, lastDate); + if (!assignWTMeteoData(meteoGridDbHandler->meteoGrid()->meteoPointPointer(assignNearestRow,assignNearestCol), firstMeteoDate)) + { + return false; + } + else + { + linkedMeteoPoint->id = meteoGridDbHandler->meteoGrid()->meteoPointPointer(assignNearestRow,assignNearestCol)->id; + linkedMeteoPoint->name = meteoGridDbHandler->meteoGrid()->meteoPointPointer(assignNearestRow,assignNearestCol)->name; + linkedMeteoPoint->latitude = meteoGridDbHandler->meteoGrid()->meteoPointPointer(assignNearestRow,assignNearestCol)->latitude; + linkedMeteoPoint->nrObsDataDaysD = meteoGridDbHandler->meteoGrid()->meteoPointPointer(assignNearestRow,assignNearestCol)->nrObsDataDaysD; + linkedMeteoPoint->obsDataD = meteoGridDbHandler->meteoGrid()->meteoPointPointer(assignNearestRow,assignNearestCol)->obsDataD; + } + } + } + else + { + int assignNearestIndex; + QDate lastDate = meteoPointsDbHandler->getLastDate(daily).date(); + for (int i = 0; i < nrMeteoPoints; i++) + { + + double utmX = meteoPoints[i].point.utm.x; + double utmY = meteoPoints[i].point.utm.y; + float myDistance = gis::computeDistance(wellUtmX, wellUtmY, utmX, utmY); + if (myDistance < MAXWELLDISTANCE ) + { + if (myDistance < minimumDistance || minimumDistance == NODATA) + { + meteoPointsDbHandler->loadDailyData(getCrit3DDate(firstMeteoDate), getCrit3DDate(lastDate), &(meteoPoints[i])); + if (assignWTMeteoData(&meteoPoints[i], firstMeteoDate)) + { + minimumDistance = myDistance; + assignNearestMeteoPoint = true; + assignNearestIndex = i; + } + } + } + } + if (assignNearestMeteoPoint) + { + linkedMeteoPoint->id = meteoPoints[assignNearestIndex].id; + linkedMeteoPoint->name = meteoPoints[assignNearestIndex].name; + linkedMeteoPoint->latitude = meteoPoints[assignNearestIndex].latitude; + linkedMeteoPoint->nrObsDataDaysD = meteoPoints[assignNearestIndex].nrObsDataDaysD; + linkedMeteoPoint->obsDataD = meteoPoints[assignNearestIndex].obsDataD; + } + } + return assignNearestMeteoPoint; +} + +bool Project::assignWTMeteoData(Crit3DMeteoPoint* linkedMeteoPoint, QDate firstMeteoDate) +{ + QDate lastMeteoDate; + lastMeteoDate.setDate(linkedMeteoPoint->getLastDailyData().year, linkedMeteoPoint->getLastDailyData().month, linkedMeteoPoint->getLastDailyData().day); // ultimo dato disponibile + float precPerc = linkedMeteoPoint->getPercValueVariable(Crit3DDate(firstMeteoDate.day(), firstMeteoDate.month(), firstMeteoDate.year()) , Crit3DDate(lastMeteoDate.day(), lastMeteoDate.month(), lastMeteoDate.year()), dailyPrecipitation); + float tMinPerc = linkedMeteoPoint->getPercValueVariable(Crit3DDate(firstMeteoDate.day(), firstMeteoDate.month(), firstMeteoDate.year()) , Crit3DDate(lastMeteoDate.day(), lastMeteoDate.month(), lastMeteoDate.year()), dailyAirTemperatureMin); + float tMaxPerc = linkedMeteoPoint->getPercValueVariable(Crit3DDate(firstMeteoDate.day(), firstMeteoDate.month(), firstMeteoDate.year()) , Crit3DDate(lastMeteoDate.day(), lastMeteoDate.month(), lastMeteoDate.year()), dailyAirTemperatureMax); + + float minPercentage = meteoSettings->getMinimumPercentage(); + if (precPerc > minPercentage/100 && tMinPerc > minPercentage/100 && tMaxPerc > minPercentage/100) + { + return true; + } + else + { + errorString = "Not enough meteo data to analyze watertable period. Try to decrease the required percentage"; + return false; + } } diff --git a/agrolib/project/project.h b/agrolib/project/project.h index 366e24afb..061ad87fa 100644 --- a/agrolib/project/project.h +++ b/agrolib/project/project.h @@ -303,6 +303,9 @@ bool waterTableImportLocation(QString csvFileName); bool waterTableImportDepths(QString csvDepths); bool computeSingleWell(QString idWell, int indexWell); + void showSingleWell(WaterTable waterTable, QString idWell); + bool assignNearestMeteoPoint(bool isMeteoGridLoaded, double wellUtmX, double wellUtmY, QDate firstMeteoDate, Crit3DMeteoPoint* linkedMeteoPoint); + bool assignWTMeteoData(Crit3DMeteoPoint* linkedMeteoPoint, QDate firstMeteoDate); private slots: void deleteMeteoWidgetPoint(int id); diff --git a/agrolib/waterTable/dialogSummary.cpp b/agrolib/waterTable/dialogSummary.cpp index fe7d2c3cb..f670d21e2 100644 --- a/agrolib/waterTable/dialogSummary.cpp +++ b/agrolib/waterTable/dialogSummary.cpp @@ -3,78 +3,79 @@ DialogSummary::DialogSummary(WaterTable myWaterTable) { setWindowTitle("Summary"); - QVBoxLayout* mainLayout = new QVBoxLayout; + QVBoxLayout* mainLayout = new QVBoxLayout(); this->resize(350, 200); + this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + this->setAttribute(Qt::WA_DeleteOnClose); - QGridLayout *infoLayout = new QGridLayout; + QGridLayout *infoLayout = new QGridLayout(); - QLabel labelId("ID: "); - QLineEdit myId(myWaterTable.getIdWell()); - myId.setReadOnly(true); + QLabel* labelId = new QLabel("ID: "); + QLineEdit* myId = new QLineEdit(myWaterTable.getIdWell()); + myId->setReadOnly(true); - QLabel labelObsData("Nr of observed depth: "); - QLineEdit myObsData(QString::number(myWaterTable.getNrObsData())); - myObsData.setReadOnly(true); + QLabel* labelObsData = new QLabel("Nr of observed depth: "); + QLineEdit* myObsData = new QLineEdit(QString::number(myWaterTable.getNrObsData())); + myObsData->setReadOnly(true); - QLabel labelAlpha("alpha [-]: "); - QLineEdit myAlpha(QString::number(myWaterTable.getAlpha(),'f', 2)); - myAlpha.setReadOnly(true); + QLabel* labelAlpha = new QLabel("alpha [-]: "); + QLineEdit* myAlpha = new QLineEdit(QString::number(myWaterTable.getAlpha(),'f', 2)); + myAlpha->setReadOnly(true); - QLabel labelH0("H0 [cm]: "); - QLineEdit myH0(QString::number((int)myWaterTable.getH0())); - myH0.setReadOnly(true); + QLabel* labelH0 = new QLabel("H0 [cm]: "); + QLineEdit* myH0 = new QLineEdit(QString::number((int)myWaterTable.getH0())); + myH0->setReadOnly(true); - QLabel labelNrDays("Nr days: "); - QLineEdit myNrDays(QString::number(myWaterTable.getNrDaysPeriod())); - myNrDays.setReadOnly(true); + QLabel* labelNrDays = new QLabel("Nr days: "); + QLineEdit* myNrDays = new QLineEdit(QString::number(myWaterTable.getNrDaysPeriod())); + myNrDays->setReadOnly(true); - QLabel labelR2("R2 [-]: "); - QLineEdit myR2(QString::number(myWaterTable.getR2(),'f', 2)); - myR2.setReadOnly(true); + QLabel* labelR2 = new QLabel("R2 [-]: "); + QLineEdit* myR2 = new QLineEdit(QString::number(myWaterTable.getR2(),'f', 2)); + myR2->setReadOnly(true); - QLabel labelRMSE("RMSE [cm]: "); - QLineEdit myRMSE(QString::number(myWaterTable.getRMSE(),'f', 2)); - myRMSE.setReadOnly(true); + QLabel* labelRMSE = new QLabel("RMSE [cm]: "); + QLineEdit* myRMSE = new QLineEdit(QString::number(myWaterTable.getRMSE(),'f', 2)); + myRMSE->setReadOnly(true); - QLabel labelNASH("Nash-Sutcliffe [-]: "); - QLineEdit myNASH(QString::number(myWaterTable.getNASH(),'f', 2)); - myNASH.setReadOnly(true); + QLabel* labelNASH = new QLabel("Nash-Sutcliffe [-]: "); + QLineEdit* myNASH = new QLineEdit(QString::number(myWaterTable.getNASH(),'f', 2)); + myNASH->setReadOnly(true); - QLabel labelEfIndex("Efficiency Index [-]: "); - QLineEdit myEfIndex(QString::number(myWaterTable.getEF(),'f', 2)); - myEfIndex.setReadOnly(true); + QLabel* labelEfIndex = new QLabel("Efficiency Index [-]: "); + QLineEdit* myEfIndex = new QLineEdit(QString::number(myWaterTable.getEF(),'f', 2)); + myEfIndex->setReadOnly(true); - infoLayout->addWidget(&labelId,0,0,1,1); - infoLayout->addWidget(&myId,0,1,1,1); + infoLayout->addWidget(labelId,0,0,1,1); + infoLayout->addWidget(myId,0,1,1,1); - infoLayout->addWidget(&labelObsData,1,0,1,1); - infoLayout->addWidget(&myObsData,1,1,1,1); + infoLayout->addWidget(labelObsData,1,0,1,1); + infoLayout->addWidget(myObsData,1,1,1,1); - infoLayout->addWidget(&labelAlpha,2,0,1,1); - infoLayout->addWidget(&myAlpha,2,1,1,1); + infoLayout->addWidget(labelAlpha,2,0,1,1); + infoLayout->addWidget(myAlpha,2,1,1,1); - infoLayout->addWidget(&labelH0,3,0,1,1); - infoLayout->addWidget(&myH0,3,1,1,1); + infoLayout->addWidget(labelH0,3,0,1,1); + infoLayout->addWidget(myH0,3,1,1,1); - infoLayout->addWidget(&labelNrDays,4,0,1,1); - infoLayout->addWidget(&myNrDays,4,1,1,1); + infoLayout->addWidget(labelNrDays,4,0,1,1); + infoLayout->addWidget(myNrDays,4,1,1,1); - infoLayout->addWidget(&labelR2,5,0,1,1); - infoLayout->addWidget(&myR2,5,1,1,1); + infoLayout->addWidget(labelR2,5,0,1,1); + infoLayout->addWidget(myR2,5,1,1,1); - infoLayout->addWidget(&labelRMSE,6,0,1,1); - infoLayout->addWidget(&myRMSE,6,1,1,1); + infoLayout->addWidget(labelRMSE,6,0,1,1); + infoLayout->addWidget(myRMSE,6,1,1,1); - infoLayout->addWidget(&labelNASH,7,0,1,1); - infoLayout->addWidget(&myNASH,7,1,1,1); + infoLayout->addWidget(labelNASH,7,0,1,1); + infoLayout->addWidget(myNASH,7,1,1,1); - infoLayout->addWidget(&labelEfIndex,8,0,1,1); - infoLayout->addWidget(&myEfIndex,8,1,1,1); + infoLayout->addWidget(labelEfIndex,8,0,1,1); + infoLayout->addWidget(myEfIndex,8,1,1,1); mainLayout->addLayout(infoLayout); setLayout(mainLayout); - show(); } DialogSummary::~DialogSummary() @@ -86,3 +87,5 @@ void DialogSummary::closeEvent(QCloseEvent *event) { event->accept(); } + + diff --git a/agrolib/waterTable/waterTable.cpp b/agrolib/waterTable/waterTable.cpp index e649777bd..c377c8202 100644 --- a/agrolib/waterTable/waterTable.cpp +++ b/agrolib/waterTable/waterTable.cpp @@ -2,10 +2,11 @@ #include "commonConstants.h" #include "weatherGenerator.h" -WaterTable::WaterTable(Crit3DMeteoPoint* meteoPoints, int nrMeteoPoints, Crit3DMeteoGrid* meteoGrid, bool isMeteoGridLoaded, Crit3DMeteoSettings meteoSettings, gis::Crit3DGisSettings gisSettings) - : meteoPoints(meteoPoints), nrMeteoPoints(nrMeteoPoints), meteoGrid(meteoGrid), isMeteoGridLoaded(isMeteoGridLoaded), meteoSettings(meteoSettings), gisSettings(gisSettings) +WaterTable::WaterTable(Crit3DMeteoPoint *linkedMeteoPoint, Crit3DMeteoSettings meteoSettings, gis::Crit3DGisSettings gisSettings) + : linkedMeteoPoint(linkedMeteoPoint), meteoSettings(meteoSettings), gisSettings(gisSettings) { - + firstMeteoDate = QDate(linkedMeteoPoint->getFirstDailyData().year, linkedMeteoPoint->getFirstDailyData().month, linkedMeteoPoint->getFirstDailyData().day); + lastMeteoDate = QDate(linkedMeteoPoint->getLastDailyData().year, linkedMeteoPoint->getLastDailyData().month, linkedMeteoPoint->getLastDailyData().day); } QString WaterTable::getIdWell() const @@ -101,7 +102,6 @@ void WaterTable::initializeWaterTable(Well myWell) WTClimateMonthly[myMonthIndex] = NODATA; } - isMeteoPointLinked = false; isCWBEquationReady = false; isClimateReady = false; @@ -127,11 +127,6 @@ bool WaterTable::computeWaterTable(Well myWell, int maxNrDays) initializeWaterTable(myWell); isClimateReady = computeWTClimate(); - isMeteoPointLinked = assignNearestMeteoPoint(); - if (isMeteoPointLinked == false) - { - return false; - } if (!computeETP_allSeries()) { @@ -185,92 +180,12 @@ bool WaterTable::computeWTClimate() return false; } WTClimateMonthly[myMonthIndex] = H_sum[myMonthIndex] / H_num[myMonthIndex]; - isClimateReady = true; - cubicSplineYearInterpolate(WTClimateMonthly, WTClimateDaily); } + isClimateReady = true; + cubicSplineYearInterpolate(WTClimateMonthly, WTClimateDaily); return true; } -bool WaterTable::assignNearestMeteoPoint() -{ - float minimumDistance = NODATA; - bool assignNearestMeteoPoint = false; - if (isMeteoGridLoaded) - { - int zoneNumber; - for (unsigned row = 0; row < unsigned(meteoGrid->gridStructure().header().nrRows); row++) - { - for (unsigned col = 0; col < unsigned(meteoGrid->gridStructure().header().nrCols); col++) - { - double utmX = meteoGrid->meteoPointPointer(row,col)->point.utm.x; - double utmY = meteoGrid->meteoPointPointer(row,col)->point.utm.y; - if (utmX == NODATA || utmY == NODATA) - { - double lat = meteoGrid->meteoPointPointer(row,col)->latitude; - double lon = meteoGrid->meteoPointPointer(row,col)->longitude; - gis::latLonToUtm(lat, lon, &utmX, &utmY, &zoneNumber); - } - float myDistance = gis::computeDistance(well.getUtmX(), well.getUtmY(), utmX, utmY); - if (myDistance < MAXWELLDISTANCE ) - { - if (myDistance < minimumDistance || minimumDistance == NODATA) - { - if (assignWTMeteoData(*meteoGrid->meteoPointPointer(row,col) )) - { - minimumDistance = myDistance; - assignNearestMeteoPoint = true; - linkedMeteoPoint = (*meteoGrid->meteoPointPointer(row,col)); - } - } - } - } - } - } - else - { - for (int i = 0; i < nrMeteoPoints; i++) - { - - double utmX = meteoPoints[i].point.utm.x; - double utmY = meteoPoints[i].point.utm.y; - float myDistance = gis::computeDistance(well.getUtmX(), well.getUtmY(), utmX, utmY); - if (myDistance < MAXWELLDISTANCE ) - { - if (myDistance < minimumDistance || minimumDistance == NODATA) - { - if (assignWTMeteoData(meteoPoints[i])) - { - minimumDistance = myDistance; - assignNearestMeteoPoint = true; - linkedMeteoPoint = meteoPoints[i]; - } - } - } - } - } - return assignNearestMeteoPoint; -} - -bool WaterTable::assignWTMeteoData(Crit3DMeteoPoint point) -{ - firstMeteoDate = firstDateWell.addDays(-730); // necessari 24 mesi di dati meteo precedenti il primo dato di falda - lastMeteoDate.setDate(point.getLastDailyData().year, point.getLastDailyData().month, point.getLastDailyData().day); // ultimo dato disponibile - float precPerc = point.getPercValueVariable(Crit3DDate(firstMeteoDate.day(), firstMeteoDate.month(), firstMeteoDate.year()) , Crit3DDate(lastMeteoDate.day(), lastMeteoDate.month(), lastMeteoDate.year()), dailyPrecipitation); - float tMinPerc = point.getPercValueVariable(Crit3DDate(firstMeteoDate.day(), firstMeteoDate.month(), firstMeteoDate.year()) , Crit3DDate(lastMeteoDate.day(), lastMeteoDate.month(), lastMeteoDate.year()), dailyAirTemperatureMin); - float tMaxPerc = point.getPercValueVariable(Crit3DDate(firstMeteoDate.day(), firstMeteoDate.month(), firstMeteoDate.year()) , Crit3DDate(lastMeteoDate.day(), lastMeteoDate.month(), lastMeteoDate.year()), dailyAirTemperatureMax); - - float minPercentage = meteoSettings.getMinimumPercentage(); - if (precPerc > minPercentage/100 && tMinPerc > minPercentage/100 && tMaxPerc > minPercentage/100) - { - return true; - } - else - { - error = "Not enough meteo data to analyze watertable period. Try to decrease the required percentage"; - return false; - } -} - bool WaterTable::computeETP_allSeries() { etpValues.clear(); @@ -283,9 +198,9 @@ bool WaterTable::computeETP_allSeries() for (QDate myDate = firstMeteoDate; myDate<=lastMeteoDate; myDate=myDate.addDays(1)) { Crit3DDate date(myDate.day(), myDate.month(), myDate.year()); - float Tmin = linkedMeteoPoint.getMeteoPointValueD(date, dailyAirTemperatureMin); - float Tmax = linkedMeteoPoint.getMeteoPointValueD(date, dailyAirTemperatureMax); - float prec = linkedMeteoPoint.getMeteoPointValueD(date, dailyPrecipitation); + float Tmin = linkedMeteoPoint->getMeteoPointValueD(date, dailyAirTemperatureMin); + float Tmax = linkedMeteoPoint->getMeteoPointValueD(date, dailyAirTemperatureMax); + float prec = linkedMeteoPoint->getMeteoPointValueD(date, dailyPrecipitation); float etp = dailyEtpHargreaves(Tmin, Tmax, date, myLat,&meteoSettings); etpValues.push_back(etp); precValues.push_back(prec); @@ -302,7 +217,7 @@ bool WaterTable::computeETP_allSeries() } else { - error = "Missing data: " + QString::fromStdString(linkedMeteoPoint.name); + error = "Missing data: " + QString::fromStdString(linkedMeteoPoint->name); return false; } @@ -325,6 +240,8 @@ bool WaterTable::computeCWBCorrelation(int maxNrDays) for (int nrDays = 90; nrDays <= maxNrDays; nrDays=nrDays+10) { + myCWBSum.clear(); + myObsWT.clear(); QMapIterator it(myDepths); while (it.hasNext()) { @@ -374,28 +291,28 @@ float WaterTable::computeCWB(QDate myDate, int nrDays) for (int shift = 1; shift<=nrDays; shift++) { actualDate = myDate.addDays(-shift); - int index = firstMeteoDate.daysTo(actualDate) + 1; // LC CONTROLLARE - if (index > 0 && index < precValues.size()) + int index = firstMeteoDate.daysTo(actualDate); + if (index >= 0 && index < precValues.size()) { float etp = etpValues[index]; float prec = precValues[index]; if ( etp != NODATA && prec != NODATA) { currentCWB = prec - etp; - weight = 1 - shift; // nrDaysPeriod + weight = 1 - (float)shift/nrDays; sumCWB = sumCWB + currentCWB * weight; nrValidDays = nrValidDays + 1; } } } - if (nrValidDays < (nrDaysPeriod * meteoSettings.getMinimumPercentage() / 100)) + if (nrValidDays < (nrDays * meteoSettings.getMinimumPercentage() / 100)) { error = "Few Data"; return NODATA; } // Climate - float climateCWB = avgDailyCWB * nrDaysPeriod * 0.5; + float climateCWB = avgDailyCWB * nrDays * 0.5; // conversion: from [mm] to [cm] float computeCWB = (sumCWB - climateCWB) * 0.1; @@ -413,24 +330,17 @@ bool WaterTable::computeWaterTableIndices() std::vector myClimate; float myIntercept; float myCoeff; - int doy1 = 1; - int doy2 = 366; while (it.hasNext()) { it.next(); QDate myDate = it.key(); int myValue = it.value(); - int myDoy = myDate.dayOfYear(); - // doesn't work for interannual period - if ((myDoy >= doy1) && (myDoy <= doy2)) + float computedValue = getWaterTableDaily(myDate); + if (computedValue != NODATA) { - float computedValue = getWaterTableDaily(myDate); - if (computedValue != NODATA) - { - myObs.push_back(myValue); - myComputed.push_back(computedValue); - myClimate.push_back(getWaterTableClimate(myDate)); - } + myObs.push_back(myValue); + myComputed.push_back(computedValue); + myClimate.push_back(getWaterTableClimate(myDate)); } } statistics::linearRegression(myObs, myComputed, myObs.size(), false, &myIntercept, &myCoeff, &R2); @@ -442,13 +352,13 @@ bool WaterTable::computeWaterTableIndices() float myErrAvg = 0; float myErrClimate = 0; - nrObsData = myObs.size(); - for (int i=0; i myDepths = well.getDepths(); QList keys = myDepths.keys(); - for (int i = 0; i0) { - if (i>0) + indexPrev = i - 1; + previousDate = keys[indexPrev]; + previosValue = myDepths[previousDate]; + } + if (i < keys.size()-1) + { + indexNext = i + 1; + nextDate = keys[indexNext]; + nextValue = myDepths[nextDate]; + } + } + else + { + for (int i = 0; i myDate) { - indexPrev = i - 1; - previousDate = keys[indexPrev]; - previosValue = myDepths[previousDate]; + indexNext = i; + nextDate = keys[indexNext]; + nextValue = myDepths[nextDate]; + break; } - if (i < keys.size()-1) + else if (keys[i] < myDate && keys[i+1] > myDate) { + indexPrev = i; + previousDate = keys[indexPrev]; + previosValue = myDepths[previousDate]; indexNext = i + 1; nextDate = keys[indexNext]; nextValue = myDepths[nextDate]; + break; } } } @@ -609,6 +542,7 @@ bool WaterTable::getWaterTableHindcast(QDate myDate, float* myValue, float* myDe { previousDz = previosValue - myWT; } + diffWithPrev = previousDate.daysTo(myDate); } if (indexNext != NODATA) { @@ -617,11 +551,10 @@ bool WaterTable::getWaterTableHindcast(QDate myDate, float* myValue, float* myDe { nextDz = nextValue - myWT; } + diffWithNext = myDate.daysTo(nextDate); } // check lenght of missing data period - int diffWithNext = myDate.daysTo(nextDate); - int diffWithPrev = previousDate.daysTo(myDate); if (previousDz != NODATA && nextDz != NODATA) { dT = previousDate.daysTo(nextDate); @@ -678,12 +611,14 @@ void WaterTable::viewWaterTableSeries() float myDelta; int myDeltaDays; - for (QDate myDate = firstMeteoDate; myDate<=lastMeteoDate; myDate=myDate.addDays(1)) + int numValues = well.getFirstDate().daysTo(lastMeteoDate) + 1; + for (int i = 0; i< numValues; i++) { + QDate myDate = well.getFirstDate().addDays(i); myDates.push_back(myDate); - float computedValue = getWaterTableDaily(myDate); + float computedValue = getWaterTableDaily(myDate.addDays(-1)); myHindcastSeries.push_back(computedValue); - getWaterTableHindcast(myDate, &myDepth, &myDelta, &myDeltaDays); + getWaterTableHindcast(myDate.addDays(-1), &myDepth, &myDelta, &myDeltaDays); myInterpolateSeries.push_back(myDepth); } } diff --git a/agrolib/waterTable/waterTable.h b/agrolib/waterTable/waterTable.h index 452c784dd..681e7b9f7 100644 --- a/agrolib/waterTable/waterTable.h +++ b/agrolib/waterTable/waterTable.h @@ -12,15 +12,13 @@ class WaterTable { public: - WaterTable(Crit3DMeteoPoint* meteoPoints, int nrMeteoPoints, Crit3DMeteoGrid* meteoGrid, bool isMeteoGridLoaded, Crit3DMeteoSettings meteoSettings, gis::Crit3DGisSettings gisSettings); + WaterTable(Crit3DMeteoPoint* linkedMeteoPoint, Crit3DMeteoSettings meteoSettings, gis::Crit3DGisSettings gisSettings); QString getIdWell() const; QDate getFirstDateWell(); QDate getLastDateWell(); void initializeWaterTable(Well myWell); bool computeWaterTable(Well myWell, int maxNrDays); bool computeWTClimate(); - bool assignNearestMeteoPoint(); - bool assignWTMeteoData(Crit3DMeteoPoint point); bool computeETP_allSeries(); bool computeCWBCorrelation(int maxNrDays); float computeCWB(QDate myDate, int nrDays); @@ -47,10 +45,7 @@ class WaterTable QMap getDepths(); private: - Crit3DMeteoPoint *meteoPoints; - int nrMeteoPoints; - Crit3DMeteoGrid *meteoGrid; - bool isMeteoGridLoaded; + Crit3DMeteoPoint* linkedMeteoPoint; Crit3DMeteoSettings meteoSettings; gis::Crit3DGisSettings gisSettings; QDate firstDateWell; @@ -76,10 +71,8 @@ class WaterTable float WTClimateDaily[366]; int nrObsData; - bool isMeteoPointLinked; bool isCWBEquationReady; float avgDailyCWB; //[mm] - Crit3DMeteoPoint linkedMeteoPoint; // graph std::vector myDates; diff --git a/agrolib/waterTable/waterTable.pro b/agrolib/waterTable/waterTable.pro index d0a04d529..c012e2a10 100644 --- a/agrolib/waterTable/waterTable.pro +++ b/agrolib/waterTable/waterTable.pro @@ -32,7 +32,7 @@ SOURCES += \ importData.cpp \ waterTable.cpp \ waterTableChartView.cpp \ - waterTableWidge.cpp \ + waterTableWidget.cpp \ well.cpp HEADERS += \ diff --git a/agrolib/waterTable/waterTableChartView.cpp b/agrolib/waterTable/waterTableChartView.cpp index 74f7cccf4..d09c02511 100644 --- a/agrolib/waterTable/waterTableChartView.cpp +++ b/agrolib/waterTable/waterTableChartView.cpp @@ -6,7 +6,7 @@ WaterTableChartView::WaterTableChartView(QWidget *parent) : obsDepthSeries = new QScatterSeries(); obsDepthSeries->setName("Observed"); obsDepthSeries->setColor(Qt::green); - obsDepthSeries->setMarkerSize(10.0); + obsDepthSeries->setMarkerSize(8.0); hindcastSeries = new QLineSeries(); hindcastSeries->setName("hindcast"); @@ -36,7 +36,7 @@ void WaterTableChartView::draw(std::vector myDates, std::vector my int nDays = myDates.size(); QDateTime myDateTime; - myDateTime.setTime(QTime(0,0)); + myDateTime.setTime(QTime(0,0,0)); for (int day = 0; day < nDays; day++) { myDateTime.setDate(myDates[day]); @@ -54,17 +54,15 @@ void WaterTableChartView::draw(std::vector myDates, std::vector my axisY->setMax(300); axisY->setMin(0); axisY->setLabelFormat("%d"); - + axisY->setTickCount(16); + axisX->setTickCount(12); QDateTime firstDateTime; - firstDateTime.setDate(myDates[0]); - firstDateTime.setTime(QTime(0,0)); + firstDateTime.setDate(myDates[0].addDays(-3)); + firstDateTime.setTime(QTime(0,0,0)); QDateTime lastDateTime; - lastDateTime.setDate(myDates[myDates.size()-1]); - lastDateTime.setTime(QTime(0,0)); - - axisX->setTickCount(12); - axisX->setMin(firstDateTime); - axisX->setMax(lastDateTime); + lastDateTime.setDate(myDates[myDates.size()-1].addDays(3)); + lastDateTime.setTime(QTime(0,0,0)); + axisX->setRange(firstDateTime, lastDateTime); chart()->addSeries(obsDepthSeries); chart()->addSeries(hindcastSeries); @@ -90,9 +88,10 @@ void WaterTableChartView::tooltipObsDepthSeries(QPointF point, bool state) { QDateTime firstDate(QDate(1970,1,1), QTime(0,0,0)); QDateTime xValue = firstDate.addMSecs(point.x()); - double yValue = point.y(); + QDate myDate = xValue.date().addDays(1); + int yValue = point.y(); - m_tooltip->setText(QString("%1: %2").arg(xValue.date().toString("yyyy/MM/dd")).arg(yValue, 0, 'd')); + m_tooltip->setText(QString("%1: %2").arg(myDate.toString("yyyy/MM/dd")).arg(yValue)); m_tooltip->setSeries(serie); m_tooltip->setAnchor(point); m_tooltip->setZValue(11); @@ -113,9 +112,10 @@ void WaterTableChartView::tooltipLineSeries(QPointF point, bool state) { QDateTime firstDate(QDate(1970,1,1), QTime(0,0,0)); QDateTime xValue = firstDate.addMSecs(point.x()); - double yValue = point.y(); + QDate myDate = xValue.date().addDays(1); + int yValue = point.y(); - m_tooltip->setText(QString("%1: %2").arg(xValue.date().toString("yyyy/MM/dd")).arg(yValue, 0, 'd')); + m_tooltip->setText(QString("%1: %2").arg(myDate.toString("yyyy/MM/dd")).arg(yValue)); m_tooltip->setSeries(serie); m_tooltip->setAnchor(point); m_tooltip->setZValue(11); diff --git a/agrolib/waterTable/waterTableWidge.cpp b/agrolib/waterTable/waterTableWidget.cpp similarity index 98% rename from agrolib/waterTable/waterTableWidge.cpp rename to agrolib/waterTable/waterTableWidget.cpp index 25cf066b0..a73061c7a 100644 --- a/agrolib/waterTable/waterTableWidge.cpp +++ b/agrolib/waterTable/waterTableWidget.cpp @@ -18,7 +18,6 @@ WaterTableWidget::WaterTableWidget(QString id, std::vector myDates, std:: setLayout(mainLayout); waterTableChartView->draw(myDates, myHindcastSeries, myInterpolateSeries, obsDepths); - show(); } WaterTableWidget::~WaterTableWidget()