Ref T415, FP functions to parse SB4 and vPilot format. SB4 implemented, vPilot not yet

This commit is contained in:
Klaus Basan
2018-10-26 01:08:05 +02:00
parent eed3eeb700
commit 437f529767
2 changed files with 146 additions and 3 deletions

View File

@@ -10,12 +10,20 @@
#include "flightplan.h"
#include "airlineicaocode.h"
#include "flightplan.h"
#include "altitude.h"
#include "blackmisc/pq/time.h"
#include "blackmisc/pq/speed.h"
#include "blackmisc/iconlist.h"
#include "blackmisc/icons.h"
#include "blackmisc/fileutils.h"
#include "blackmisc/stringutils.h"
#include <QFile>
#include <QDateTime>
#include <QStringBuilder>
#include <QRegularExpression>
using namespace BlackMisc::Network;
using namespace BlackMisc::PhysicalQuantities;
namespace BlackMisc
{
@@ -113,7 +121,6 @@ namespace BlackMisc
}
}
QString CFlightPlanRemarks::cut(const QString &remarks, const QString &marker)
{
const int maxIndex = remarks.size() - 1;
@@ -137,6 +144,12 @@ namespace BlackMisc
return cut;
}
const CLogCategoryList &CFlightPlan::getLogCategories()
{
static const CLogCategoryList cats { CLogCategory::flightPlan() };
return cats;
}
CFlightPlan::CFlightPlan() { }
CFlightPlan::CFlightPlan(const CCallsign &callsign, const QString &equipmentIcao, const CAirportIcaoCode &originAirportIcao, const CAirportIcaoCode &destinationAirportIcao,
@@ -256,6 +269,116 @@ namespace BlackMisc
return s;
}
CFlightPlan CFlightPlan::fromVPilotFormat(const QString &vPilotData)
{
if (vPilotData.isEmpty()) { return CFlightPlan(); }
return CFlightPlan();
}
CFlightPlan CFlightPlan::fromSB4Format(const QString &sbData)
{
if (sbData.isEmpty()) { return CFlightPlan(); }
CFlightPlan fp;
const QMap<QString, QString> values = parseIniValues(sbData);
const QString altStr = values.value("Altitude");
const CAltitude alt(altStr.length() < 4 ? "FL" + altStr : altStr);
const QString type = values.value("Type"); // IFR/VFR
fp.setFlightRule(type == "0" ? IFR : VFR);
const int fuelMins = values.value("FuelMinutes").toInt() + 60 * values.value("FuelHours").toInt();
const CTime fuelTime(fuelMins, CTimeUnit::min());
const int enrouteMins = values.value("FlightMinutes").toInt() + 60 * values.value("FlightHours").toInt();
const CTime enrouteTime(enrouteMins, CTimeUnit::min());
fp.setOriginAirportIcao(values.value("Departure"));
fp.setDestinationAirportIcao(values.value("Arrival"));
fp.setAlternateAirportIcao(values.value("Alternate"));
fp.setRemarks(values.value("Remarks"));
fp.setRoute(values.value("Route"));
fp.setCruiseAltitude(alt);
fp.setFuelTime(fuelTime);
fp.setEnrouteTime(enrouteTime);
fp.setTakeoffTimePlanned(QDateTime::currentDateTimeUtc());
int airspeedKts = values.value("Airspeed").toInt();
const CSpeed airspeed(airspeedKts, CSpeedUnit::kts());
fp.setCruiseTrueAirspeed(airspeed);
const bool heavy = stringToBool(values.value("Heavy"));
if (heavy) { fp.setPrefix("H"); }
return fp;
}
CFlightPlan CFlightPlan::fromMultipleFormats(const QString &data)
{
if (data.isEmpty()) { return CFlightPlan(); }
if (data.contains("[SBFlightPlan]", Qt::CaseInsensitive)) { return CFlightPlan::fromSB4Format(data); }
if (data.contains("<FlightPlan", Qt::CaseInsensitive) && data.contains("<?xml", Qt::CaseInsensitive)) { return CFlightPlan::fromVPilotFormat(data); }
return CFlightPlan::fromJson(data);
}
CFlightPlan CFlightPlan::fromMultipleFormatsNoThrow(const QString &data)
{
CFlightPlan fp;
try
{
fp = CFlightPlan::fromMultipleFormats(data);
}
catch (const CJsonException &ex)
{
const CStatusMessage m = ex.toStatusMessage(getLogCategories(), QString("Parsing flight plan from failed."));
Q_UNUSED(m);
}
return fp;
}
CFlightPlan CFlightPlan::loadFromMultipleFormats(const QString &fileName, CStatusMessageList *msgs)
{
try
{
if (fileName.isEmpty())
{
if (msgs) { msgs->push_back(CStatusMessage(getLogCategories()).validationError("No file name")); }
return CFlightPlan();
}
else
{
QFile f(fileName);
if (!f.exists())
{
if (msgs) { msgs->push_back(CStatusMessage(getLogCategories()).validationError("File '%1' does not exist") << fileName); }
return CFlightPlan();
}
}
const QString data = CFileUtils::readFileToString(fileName);
if (data.isEmpty())
{
if (msgs) { msgs->push_back(CStatusMessage(getLogCategories()).validationError("File '%1' does not contain data") << fileName); }
return CFlightPlan();
}
if (fileName.endsWith(".sfp", Qt::CaseInsensitive)) { return CFlightPlan::fromSB4Format(data); }
if (fileName.endsWith(".vfp", Qt::CaseInsensitive)) { return CFlightPlan::fromVPilotFormat(data); }
if (fileName.endsWith(".json", Qt::CaseInsensitive)) { return CFlightPlan::fromJson(data); }
return CFlightPlan::fromMultipleFormats(data);
}
catch (const CJsonException &ex)
{
if (msgs)
{
msgs->push_back(ex.toStatusMessage(getLogCategories(), QString("Parsing flight plan from '%1' failed.").arg(fileName)));
}
}
return CFlightPlan();
}
const QString CFlightPlan::flightRuleToString(CFlightPlan::FlightRules rule)
{
switch (rule)

View File

@@ -22,6 +22,8 @@
#include "blackmisc/pq/speed.h"
#include "blackmisc/pq/time.h"
#include "blackmisc/pq/units.h"
#include "blackmisc/statusmessagelist.h"
#include "blackmisc/logcategorylist.h"
#include "blackmisc/timestampbased.h"
#include "blackmisc/valueobject.h"
#include "blackmisc/metaclass.h"
@@ -139,6 +141,9 @@ namespace BlackMisc
public ITimestampBased
{
public:
//! The log. catgeories
static const CLogCategoryList &getLogCategories();
//! Flight rules (VFR or IFR)
enum FlightRules
{
@@ -162,7 +167,7 @@ namespace BlackMisc
//! \fixme max.length of complete flight plan is 768 characters, this here is an assumption and should be part of the underlying network layers
// https://forums.vatsim.net/viewtopic.php?f=6&t=63416
static constexpr int MaxRemarksLength = 256; //!< Max.remarks length
static constexpr int MaxRouteLength = 256; //!< Max.route length
static constexpr int MaxRouteLength = 256; //!< Max.route length
//! Default constructor
CFlightPlan();
@@ -345,6 +350,21 @@ namespace BlackMisc
//! \copydoc BlackMisc::Mixin::String::toQString()
QString convertToQString(bool i18n = false) const;
//! From vPilot data
static CFlightPlan fromVPilotFormat(const QString &vPilotData);
//! From SB4 data
static CFlightPlan fromSB4Format(const QString &sbData);
//! From multiple formats
static CFlightPlan fromMultipleFormats(const QString &data);
//! From multiple formats
static CFlightPlan fromMultipleFormatsNoThrow(const QString &data);
//! Load from multiple formats
static CFlightPlan loadFromMultipleFormats(const QString &fileName, CStatusMessageList *msgs = nullptr);
//! Rules to string
static const QString flightRuleToString(FlightRules rule);