Переглянути джерело

Refactoring of Calc Namespace

Calc namespace refactored to use new DB API.

Tails table adjusted for better handling of aircraft properties. NewTailDialog and NewFlightDialog adjusted accordingly.
Felix Turo 4 роки тому
батько
коміт
146f850e15

+ 95 - 69
src/functions/acalc.cpp

@@ -1,7 +1,9 @@
 #include "acalc.h"
 #include "src/testing/adebug.h"
+#include "src/experimental/adatabase.h"
 
 using namespace ACalc;
+using namespace experimental;
 
 /*!
  * \brief ACalc::formatTimeInput verifies user input and formats to hh:mm
@@ -82,30 +84,28 @@ double ACalc::greatCircleDistance(double lat1, double lon1, double lat2, double
 }
 
 
-double ACalc::greatCircleDistanceBetweenAirports(QString dept, QString dest)
+double ACalc::greatCircleDistanceBetweenAirports(const QString &dept, const QString &dest)
 {
-    QVector<QString> dept_coordinates = Db::multiSelect({"lat", "long"}, "airports", "icao", dept,
-                                                       Db::exactMatch);
-    QVector<QString> dest_coordinates = Db::multiSelect({"lat", "long"}, "airports", "icao", dest,
-                                                       Db::exactMatch);
-
-    if (dept_coordinates.isEmpty() || dest_coordinates.isEmpty()
-       ) {
-        DEB("invalid input. aborting.");
+    auto statement = "SELECT lat, long FROM airports WHERE icao = '" + dept;
+    statement.append("' OR icao = '" + dest + "'");
+    auto lat_lon = aDB()->customQuery(statement, 2);
+
+    if (lat_lon.length() != 4) {
+        DEB("Invalid input. Aborting.");
         return 0;
     }
 
-    double lat1 = degToRad(dept_coordinates[0].toDouble());
-    double lon1 = degToRad(dept_coordinates[1].toDouble());
-    double lat2 = degToRad(dest_coordinates[0].toDouble());
-    double lon2 = degToRad(dest_coordinates[1].toDouble());
+    double dept_lat = degToRad(lat_lon[0].toDouble());
+    double dept_lon = degToRad(lat_lon[1].toDouble());
+    double dest_lat = degToRad(lat_lon[2].toDouble());
+    double dest_lon = degToRad(lat_lon[3].toDouble());
 
     // Haversine Formula
-    double delta_lon = lon2 - lon1;
-    double delta_lat = lat2 - lat1;
+    double delta_lon = dest_lon - dept_lon;
+    double delta_lat = dest_lat - dept_lat;
 
     double result = pow(sin(delta_lat / 2), 2) +
-                    cos(lat1) * cos(lat2) * pow(sin(delta_lon / 2), 2);
+                    cos(dept_lat) * cos(dest_lat) * pow(sin(delta_lon / 2), 2);
     result = 2 * asin(sqrt(result));
     return radToNauticalMiles(result);
 }
@@ -204,25 +204,24 @@ double ACalc::solarElevation(QDateTime utc_time_point, double lat, double lon)
 
 int ACalc::calculateNightTime(const QString &dept, const QString &dest, QDateTime departureTime, int tblk, int nightAngle)
 {
-    QVector<QString> dept_coordinates = Db::multiSelect({"lat", "long"}, "airports", "icao", dept,
-                                                       Db::exactMatch);
-    QVector<QString> dest_coordinates = Db::multiSelect({"lat", "long"}, "airports", "icao", dest,
-                                                       Db::exactMatch);
-
-    if (dept_coordinates.isEmpty() || dest_coordinates.isEmpty()
-       ) {
-        DEB("invalid input. aborting.");
+
+    auto statement = "SELECT lat, long FROM airports WHERE icao = '" + dept;
+    statement.append("' OR icao = '" + dest + "'");
+    auto lat_lon = aDB()->customQuery(statement, 2);
+
+    if (lat_lon.length() != 4) {
+        DEB("Invalid input. Aborting.");
         return 0;
     }
 
-    double dept_lat = degToRad(dept_coordinates[0].toDouble());
-    double dept_lon = degToRad(dept_coordinates[1].toDouble());
-    double dest_lat = degToRad(dest_coordinates[0].toDouble());
-    double dest_lon = degToRad(dest_coordinates[1].toDouble());
+    double dept_lat = degToRad(lat_lon[0].toDouble());
+    double dept_lon = degToRad(lat_lon[1].toDouble());
+    double dest_lat = degToRad(lat_lon[2].toDouble());
+    double dest_lon = degToRad(lat_lon[3].toDouble());
 
-    QVector<QVector<double>> route = intermediatePointsOnGreatCircle(dept_lat, dept_lon, dest_lat, dest_lon,
+    QVector<QVector<double>> route = intermediatePointsOnGreatCircle(dept_lat, dept_lon,
+                                                                     dest_lat, dest_lon,
                                                                      tblk);
-
     int night_time = 0;
     for (int i = 0; i < tblk ; i++) {
         if (solarElevation(departureTime.addSecs(60 * i), radToDeg(route[i][0]),
@@ -233,19 +232,20 @@ int ACalc::calculateNightTime(const QString &dept, const QString &dest, QDateTim
     return night_time;
 }
 
-bool ACalc::isNight(QString icao, QDateTime event_time, int nightAngle)
+bool ACalc::isNight(const QString &icao, QDateTime event_time, int night_angle)
 {
-    QVector<QString> coordinates = Db::multiSelect({"lat", "long"}, "airports", "icao", icao,
-                                                       Db::exactMatch);
-    if (coordinates.isEmpty()) {
-        DEB("invalid input. aborting.");
-        return false;
+    auto statement = "SELECT lat, long FROM airports WHERE icao = '" + icao + "'";
+    auto lat_lon = aDB()->customQuery(statement, 2);
+
+    if (lat_lon.length() != 2) {
+        DEB("Invalid input. Aborting.");
+        return 0;
     }
 
-    double lat = degToRad(coordinates[0].toDouble());
-    double lon = degToRad(coordinates[1].toDouble());
+    double lat = degToRad(lat_lon[0].toDouble());
+    double lon = degToRad(lat_lon[1].toDouble());
 
-    if(solarElevation(event_time, lat, lon) < nightAngle){
+    if(solarElevation(event_time, lat, lon) < night_angle){
         return true;
     } else {
         return false;
@@ -262,50 +262,76 @@ bool ACalc::isNight(QString icao, QDateTime event_time, int nightAngle)
 void ACalc::updateAutoTimes(int acft_id)
 {
     //find all flights for aircraft
-    auto flight_list = Db::multiSelect({"flight_id"},"flights","acft",
-                                      QString::number(acft_id),Db::exactMatch);
-    auto acft = Aircraft(acft_id);
+    auto statement = "SELECT flight_id FROM flights WHERE acft = " + QString::number(acft_id);
+    auto flight_list = aDB()->customQuery(statement, 1);
+
+    if (flight_list.isEmpty()) {
+        DEB("No flights for this tail found.");
+        return;
+    }
+
+    DEB("Updating " << flight_list.length() << " flights with this aircraft.");
+
+    auto acft = aDB()->getTailEntry(acft_id);
+    auto acft_data = acft.getData();
     for (const auto& item : flight_list) {
-        auto flt = Flight(item.toInt());
 
-        if(acft.data.value("singlepilot") == "1" && acft.data.value("singleengine") == "1") {
+        auto flight = aDB()->getFlightEntry(item.toInt());
+        auto flight_data = flight.getData();
+
+        if(acft_data.value("multipilot") == "0" && acft_data.value("multiengine") == "0") {
             DEB("SPSE");
-            flt.data.insert("tSPSE",flt.data.value("tblk"));
-            flt.data.insert("tSPME","");
-            flt.data.insert("tMP","");
-        } else if ((acft.data.value("singlepilot") == "1" && acft.data.value("multiengine") == "1")) {
+            flight_data.insert("tSPSE", flight_data.value("tblk"));
+            flight_data.insert("tSPME", "");
+            flight_data.insert("tMP", "");
+        } else if ((acft_data.value("multipilot") == "0" && acft.getData().value("multiengine") == "1")) {
             DEB("SPME");
-            flt.data.insert("tSPME",flt.data.value("tblk"));
-            flt.data.insert("tSPSE","");
-            flt.data.insert("tMP","");
-        } else if ((acft.data.value("multipilot") == "1")) {
+            flight_data.insert("tSPME", flight_data.value("tblk"));
+            flight_data.insert("tSPSE", "");
+            flight_data.insert("tMP", "");
+        } else if ((acft_data.value("multipilot") == "1")) {
             DEB("MPME");
-            flt.data.insert("tMP",flt.data.value("tblk"));
-            flt.data.insert("tSPSE","");
-            flt.data.insert("tSPME","");
+            flight_data.insert("tMP", flight_data.value("tblk"));
+            flight_data.insert("tSPSE", "");
+            flight_data.insert("tSPME", "");
         }
-        flt.commit();
+        flight.setData(flight_data);
+        aDB()->commit(flight);
     }
 }
 /*!
- * \brief ACalc::updateNightTimes updates the night times in the database
+ * \brief ACalc::updateNightTimes updates the night times in the database,
+ * used when changing night angle setting for example
  */
 void ACalc::updateNightTimes()
 {
-    const int nightAngle = ASettings::read("flightlogging/nightangle").toInt();
-    auto flights = Db::multiSelect({"flight_id"}, "flights");
-    for (const auto& item : flights) {
-        auto flt = new Flight(item.toInt());
-        auto dateTime = QDateTime(QDate::fromString(flt->data.value("doft"),Qt::ISODate),
-                                  QTime().addSecs(flt->data.value("tofb").toInt() * 60),
+    const int night_angle = ASettings::read("flightlogging/nightangle").toInt();
+
+    //find all flights for aircraft
+    auto statement = "SELECT ROWID FROM flights";
+    auto flight_list = aDB()->customQuery(statement, 1);
+
+    if (flight_list.isEmpty()) {
+        DEB("No flights found.");
+        return;
+    }
+    DEB("Updating " << flight_list.length() << " flights in the database.");
+
+    for (const auto& item : flight_list) {
+
+        auto flt = aDB()->getFlightEntry(item.toInt());
+        auto data = flt.getData();
+        auto dateTime = QDateTime(QDate::fromString(data.value("doft"),Qt::ISODate),
+                                  QTime().addSecs(data.value("tofb").toInt() * 60),
                                   Qt::UTC);
-        flt->data.insert("tNIGHT", QString::number(
-                             calculateNightTime(flt->data.value("dept"),
-                             flt->data.value("dest"),
+        data.insert("tNIGHT", QString::number(
+                             calculateNightTime(data.value("dept"),
+                             data.value("dest"),
                              dateTime,
-                             flt->data.value("tblk").toInt(),
-                             nightAngle)));
-        flt->commit();
+                             data.value("tblk").toInt(),
+                             night_angle)));
+        flt.setData(data);
+        aDB()->commit(flt);
     }
 }
 

+ 2 - 2
src/functions/acalc.h

@@ -134,7 +134,7 @@ double greatCircleDistance(double lat1, double lon1, double lat2, double lon2);
  * \param dest ICAO 4-letter Airport Identifier
  * \return Nautical Miles From Departure to Destination
  */
-double greatCircleDistanceBetweenAirports(QString dept, QString dest);
+double greatCircleDistanceBetweenAirports(const QString &dept, const QString &dest);
 
 /*!
  * \brief  Calculates a list of points (lat,lon) along the Great Circle between two points.
@@ -181,7 +181,7 @@ double solarElevation(QDateTime utc_time_point, double lat, double lon);
  */
 int calculateNightTime(const QString &dept, const QString &dest, QDateTime departureTime, int tblk, int nightAngle);
 
-bool isNight(QString icao, QDateTime event_time, int nightAngle);
+bool isNight(const QString &icao, QDateTime event_time, int night_angle);
 
 QString formatTimeInput(QString user_input);
 

+ 17 - 19
src/gui/dialogues/newflightdialog.cpp

@@ -400,13 +400,15 @@ void NewFlightDialog::fillDeductibleData()
     auto acft = aDB()->getTailEntry(tailsIdMap.value(ui->acftLineEdit->text()));
     if (acft.getData().isEmpty())
         DEB("Error: No valid aircraft object available, unable to deterime auto times.");
+
+
     // SP SE
-    if(acft.getData().value("singlepilot") == "1" && acft.getData().value("singleengine") == "1"){
+    if(acft.getData().value("multipilot") == "0" && acft.getData().value("multiengine") == "0"){
         ui->tSPSETimeLineEdit->setText(block_time);
         ui->tSPSELabel->setText(block_time);
     }
     // SP ME
-    if(acft.getData().value("singlepilot") == "1" && acft.getData().value("multiengine") == "1"){
+    if(acft.getData().value("multipilot") == "0" && acft.getData().value("multiengine") == "1"){
         ui->tSPMETimeLineEdit->setText(block_time);
         ui->tSPMELabel->setText(block_time);
     }
@@ -499,23 +501,19 @@ TableData NewFlightDialog::collectInput()
     newData.insert("thirdPilot", QString::number(pilotsIdMap.value(ui->thirdPilotNameLineEdit->text())));
 
     // Extra Times
-    auto acft = ATailEntry(newData.value("acft").toInt());
-    if (acft.getData().isEmpty())
-        DEB("Invalid Aircraft. Unable to automatically determine extra times.");
-
-    if (acft.getData().value("multipilot") == "1") {
-        newData.insert("tSPSE", "");
-        newData.insert("tSPME", "");
-        newData.insert("tMP", block_minutes);
-    } else if (acft.getData().value("singlepilot") == "1" && acft.getData().value("singleengine") == "1") {
-        newData.insert("tSPSE", block_minutes);
-        newData.insert("tSPME", "");
-        newData.insert("tMP", "");
-    } else if (acft.getData().value("singlepilot") == "1" && acft.getData().value("multiengine") == "1") {
-        newData.insert("tSPSE", "");
-        newData.insert("tSPME", block_minutes);
-        newData.insert("tMP", "");
-    }
+    ui->tSPSETimeLineEdit->text().isEmpty() ?
+                newData.insert("tSPSE", "")
+              : newData.insert("tSPSE", QString::number(
+                                   ACalc::stringToMinutes(ui->tSPSETimeLineEdit->text())));
+
+    ui->tSPMETimeLineEdit->text().isEmpty() ?
+                newData.insert("tSPME", "")
+              : newData.insert("tSPME", QString::number(
+                                   ACalc::stringToMinutes(ui->tSPSETimeLineEdit->text())));
+    ui->tMPTimeLineEdit->text().isEmpty() ?
+                newData.insert("tMP", "")
+              : newData.insert("tMP", QString::number(
+                                   ACalc::stringToMinutes(ui->tSPSETimeLineEdit->text())));
 
     if (ui->IfrCheckBox->isChecked()) {
         newData.insert("tIFR", block_minutes);

+ 18 - 33
src/gui/dialogues/newtaildialog.cpp

@@ -122,25 +122,18 @@ void NewTailDialog::fillForm(experimental::AEntry entry, bool is_template)
     if (is_template)
         line_edits.removeOne(ui->registrationLineEdit);
 
+    auto data = entry.getData();
+
     for (const auto &le : line_edits) {
         QString name = le->objectName().remove("LineEdit");
-        QString value = entry.getData().value(name);
+        QString value = data.value(name);
         le->setText(value);
     }
-    //select comboboxes
-    QVector<QString> operation = {entry.getData().value("singleengine"), entry.getData().value("multiengine")};
-    QVector<QString> ppNumber =  {entry.getData().value("singlepilot"), entry.getData().value("multipilot")};
-    QVector<QString> ppType =    {entry.getData().value("unpowered"), entry.getData().value("piston"),
-                                  entry.getData().value("turboprop"), entry.getData().value("jet")
-                                 };
-    QVector<QString> weight =    {entry.getData().value("light"), entry.getData().value("medium"),
-                                  entry.getData().value("heavy"), entry.getData().value("super")
-                                 };
-
-    ui->operationComboBox->setCurrentIndex(operation.indexOf("1") + 1);
-    ui->ppNumberComboBox->setCurrentIndex(ppNumber.indexOf("1") + 1);
-    ui->ppTypeComboBox->setCurrentIndex(ppType.indexOf("1") + 1);
-    ui->weightComboBox->setCurrentIndex(weight.indexOf("1") + 1);
+
+    ui->operationComboBox->setCurrentIndex(data.value("multipilot").toInt() + 1);
+    ui->ppNumberComboBox->setCurrentIndex(data.value("multiengine").toInt() + 1);
+    ui->ppTypeComboBox->setCurrentIndex(data.value("engineType").toInt() + 1);
+    ui->weightComboBox->setCurrentIndex(data.value("weightClass").toInt() + 1);
 }
 
 /*!
@@ -202,27 +195,18 @@ void NewTailDialog::submitForm()
         QString name = le->objectName().remove("LineEdit");
         new_data.insert(name, le->text());
     }
-    //prepare comboboxes
-    QVector<QString> operation = {"singlepilot", "multipilot"};
-    QVector<QString> ppNumber  = {"singleengine", "multiengine"};
-    QVector<QString> ppType    = {"unpowered", "piston",
-                                  "turboprop", "jet"
-                                 };
-    QVector<QString> weight    = {"light", "medium",
-                                  "heavy", "super"
-                                 };
-
-    if (ui->operationComboBox->currentIndex() != 0) {
-        new_data.insert(operation[ui->operationComboBox->currentIndex() - 1], QLatin1String("1"));
+
+    if (ui->operationComboBox->currentIndex() != 0) { // bool Multipilot
+        new_data.insert("multipilot", QString::number(ui->operationComboBox->currentIndex() - 1));
     }
-    if (ui->ppNumberComboBox->currentIndex() != 0) {
-        new_data.insert(ppNumber[ui->ppNumberComboBox->currentIndex() - 1], QLatin1String("1"));
+    if (ui->ppNumberComboBox->currentIndex() != 0) { // bool MultiEngine
+        new_data.insert("multiengine", QString::number(ui->ppNumberComboBox->currentIndex() - 1));
     }
-    if (ui->ppTypeComboBox->currentIndex() != 0) {
-        new_data.insert(ppType[ui->ppTypeComboBox->currentIndex() - 1], QLatin1String("1"));
+    if (ui->ppTypeComboBox->currentIndex() != 0) { // int 0=unpowered,....4=jet
+        new_data.insert("engineType", QString::number(ui->ppTypeComboBox->currentIndex() - 1));
     }
-    if (ui->weightComboBox->currentIndex() != 0) {
-        new_data.insert(weight[ui->weightComboBox->currentIndex() - 1], QLatin1String("1"));
+    if (ui->weightComboBox->currentIndex() != 0) { // int 0=light...3=super
+        new_data.insert("weightClass", QString::number(ui->weightComboBox->currentIndex() - 1));
     }
 
     //create db object
@@ -236,6 +220,7 @@ void NewTailDialog::submitForm()
         message_box.exec();
         return;
     } else {
+        ACalc::updateAutoTimes(entry.getPosition().second);
         QDialog::accept();
     }
 }