mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-06 01:45:38 +08:00
refactor: Remove weather support
This commit is contained in:
@@ -17,8 +17,6 @@
|
||||
|
||||
using namespace BlackMisc;
|
||||
using namespace BlackMisc::Aviation;
|
||||
using namespace BlackMisc::PhysicalQuantities;
|
||||
using namespace BlackMisc::Weather;
|
||||
|
||||
namespace BlackMisc::Simulation::Fsx
|
||||
{
|
||||
@@ -200,262 +198,12 @@ namespace BlackMisc::Simulation::Fsx
|
||||
return lightMask;
|
||||
}
|
||||
|
||||
QString CSimConnectUtilities::convertToSimConnectMetar(const CGridPoint &gridPoint, bool isFSX, bool useWindLayers, bool useVisibilityLayers, bool useCloudLayers, bool useTempLayers)
|
||||
{
|
||||
// STATION ID
|
||||
Q_ASSERT(!gridPoint.getIdentifier().isEmpty());
|
||||
QString simconnectMetar = gridPoint.getIdentifier();
|
||||
|
||||
// SURFACE WINDS/WINDS ALOFT
|
||||
const CWindLayerList windLayers = useWindLayers ? gridPoint.getWindLayers().sortedBy(&CWindLayer::getLevel) : CWindLayerList();
|
||||
simconnectMetar += windsToSimConnectMetar(windLayers, isFSX);
|
||||
|
||||
// VISIBILITY
|
||||
const CVisibilityLayerList visibilityLayers = useVisibilityLayers ? gridPoint.getVisibilityLayers().sortedBy(&CVisibilityLayer::getBase) : CVisibilityLayerList();
|
||||
simconnectMetar += visibilitiesToSimConnectMetar(visibilityLayers);
|
||||
|
||||
// PRESENT CONDITIONS
|
||||
// todo
|
||||
|
||||
// PARTIAL OBSCURATION
|
||||
// todo
|
||||
|
||||
// SKY CONDITIONS
|
||||
const CCloudLayerList cloudLayers = useCloudLayers ? gridPoint.getCloudLayers().sortedBy(&CCloudLayer::getBase) : CCloudLayerList();
|
||||
simconnectMetar += cloudsToSimConnectMetar(cloudLayers);
|
||||
|
||||
// TEMPERATURE
|
||||
const CTemperatureLayerList temperatureLayers = useTempLayers ? gridPoint.getTemperatureLayers().sortedBy(&CTemperatureLayer::getLevel) : CTemperatureLayerList();
|
||||
simconnectMetar += temperaturesToSimConnectMetar(temperatureLayers);
|
||||
|
||||
// ALTIMETER
|
||||
// Format:
|
||||
// QNNNN
|
||||
// Q = specifier for altimeter in millibars
|
||||
// NNNN = altimeter in millibars
|
||||
if (!gridPoint.getPressureAtMsl().isNull())
|
||||
{
|
||||
static const QString arg1s(" Q%1");
|
||||
const int altimeter = gridPoint.getPressureAtMsl().valueInteger(CPressureUnit::mbar());
|
||||
simconnectMetar += arg1s.arg(altimeter, 4, 10, QLatin1Char('0'));
|
||||
}
|
||||
return simconnectMetar.simplified();
|
||||
}
|
||||
|
||||
void CSimConnectUtilities::registerMetadata()
|
||||
{
|
||||
qRegisterMetaType<CSimConnectUtilities::SIMCONNECT_EXCEPTION>();
|
||||
qRegisterMetaType<CSimConnectUtilities::SIMCONNECT_SURFACE>();
|
||||
}
|
||||
|
||||
QString CSimConnectUtilities::windsToSimConnectMetar(const CWindLayerList &windLayers, bool isFSX)
|
||||
{
|
||||
static const QString arg1s("%1");
|
||||
|
||||
QString simConnectWinds;
|
||||
bool surface = true;
|
||||
for (const CWindLayer &windLayer : windLayers)
|
||||
{
|
||||
simConnectWinds += QLatin1Char(' ');
|
||||
|
||||
// Format:
|
||||
// DDDSSSUUU (steady)
|
||||
// DDDSSSGXXUUU (gusts)
|
||||
if (windLayer.isDirectionVariable())
|
||||
{
|
||||
// DDD = VRB for variable
|
||||
simConnectWinds += QLatin1String("VRB");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!windLayer.getSpeed().isNull() && !windLayer.getDirection().isNull())
|
||||
{
|
||||
const int speedKts = windLayer.getSpeed().valueInteger(CSpeedUnit::kts());
|
||||
const int directionDeg = windLayer.getDirection().valueInteger(CAngleUnit::deg());
|
||||
|
||||
simConnectWinds += arg1s.arg(directionDeg, 3, 10, QLatin1Char('0')) % // DDD = Direction (0-360 degrees)
|
||||
arg1s.arg(speedKts, 3, 10, QLatin1Char('0')); // SSS = Speed
|
||||
}
|
||||
}
|
||||
// XX = Gust speed
|
||||
const int gustSpeedKts = windLayer.getGustSpeed().valueInteger(CSpeedUnit::kts());
|
||||
if (gustSpeedKts > 0) { simConnectWinds += u'G' % arg1s.arg(gustSpeedKts, 2, 10, QLatin1Char('0')); }
|
||||
|
||||
// UUU = Speed units
|
||||
simConnectWinds += QStringLiteral("KT");
|
||||
|
||||
if (surface)
|
||||
{
|
||||
// Surface extension:
|
||||
// &DNNNNTS
|
||||
static const QString surfaceWinds =
|
||||
"&D" // D = specifier for surface layer
|
||||
"305" // Surface default depth is 1000 feet or 305m
|
||||
"NG"; // We don't have turbulence or wind shear information, hence we use the defaults
|
||||
simConnectWinds += surfaceWinds;
|
||||
surface = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
CAltitude altitude = windLayer.getLevel();
|
||||
|
||||
// this seems to crash FSX, P3D works
|
||||
// https://www.fsdeveloper.com/forum/threads/setting-winds-aloft.18862/
|
||||
if (!altitude.isNull() && !isFSX)
|
||||
{
|
||||
altitude.toMeanSeaLevel();
|
||||
int altitudeValueMeters = altitude.valueInteger(CLengthUnit::m());
|
||||
|
||||
// Winds aloft extension:
|
||||
// &ANNNNTS
|
||||
simConnectWinds +=
|
||||
u"&A" % // A = specifier for altitude above mean sea-level (MSL)
|
||||
arg1s.arg(altitudeValueMeters, 4, 10, QLatin1Char('0')) % // NNNN = depth (height) in meters.
|
||||
u"NG"; // We don't have turbulence or wind shear information, hence we use the defaults
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return QStringLiteral(" ") % simConnectWinds.simplified();
|
||||
}
|
||||
|
||||
QString CSimConnectUtilities::visibilitiesToSimConnectMetar(const CVisibilityLayerList &visibilityLayers)
|
||||
{
|
||||
// There are several format options, we use the meter format:
|
||||
// NNNND&BXXXX&DYYYY
|
||||
QString simconnectVisibilities;
|
||||
for (const auto &visibilityLayer : visibilityLayers)
|
||||
{
|
||||
simconnectVisibilities += QLatin1Char(' ');
|
||||
|
||||
// NNNN = in meters
|
||||
auto visibility = visibilityLayer.getVisibility().valueInteger(CLengthUnit::m());
|
||||
visibility = qMin(9999, visibility);
|
||||
simconnectVisibilities += QStringLiteral("%1").arg(visibility, 4, 10, QLatin1Char('0'));
|
||||
|
||||
// D = directional variation
|
||||
// We set NDV - no directional variation
|
||||
simconnectVisibilities += QLatin1String("NDV");
|
||||
|
||||
// XXXX = base of visibility layer in meters
|
||||
const auto base = visibilityLayer.getBase().valueInteger(CLengthUnit::m());
|
||||
simconnectVisibilities += QStringLiteral("&B%1").arg(base, 4, 10, QLatin1Char('0'));
|
||||
|
||||
// YYYY = depth of visibility layer in meters
|
||||
const auto depth = visibilityLayer.getTop().valueInteger(CLengthUnit::m());
|
||||
simconnectVisibilities += QStringLiteral("&D%1").arg(depth, 4, 10, QLatin1Char('0'));
|
||||
}
|
||||
return simconnectVisibilities;
|
||||
}
|
||||
|
||||
QString CSimConnectUtilities::cloudsToSimConnectMetar(const CCloudLayerList &cloudLayers)
|
||||
{
|
||||
// Format:
|
||||
// CCCNNN&BXXXX&DYYYY
|
||||
QString simconnectClouds;
|
||||
static const QString arg1s("%1");
|
||||
for (const CCloudLayer &cloudLayer : cloudLayers)
|
||||
{
|
||||
simconnectClouds += QLatin1Char(' ');
|
||||
|
||||
// CCC = Coverage string
|
||||
switch (cloudLayer.getCoverage())
|
||||
{
|
||||
case CCloudLayer::None: simconnectClouds += QLatin1String("CLR"); break;
|
||||
case CCloudLayer::Few: simconnectClouds += QLatin1String("FEW"); break;
|
||||
case CCloudLayer::Broken: simconnectClouds += QLatin1String("BKN"); break;
|
||||
case CCloudLayer::Overcast: simconnectClouds += QLatin1String("OVC"); break;
|
||||
case CCloudLayer::Scattered:
|
||||
default:
|
||||
simconnectClouds += QLatin1String("SCT");
|
||||
}
|
||||
|
||||
// NNN = coded height
|
||||
// If NNN is 999 the level is 100,000 feet, otherwise it is 100 x NNN in feet
|
||||
auto level = cloudLayer.getTop().valueInteger(CLengthUnit::ft()) / 100;
|
||||
// Ignore clouds higher than 99900 feet
|
||||
if (level > 999) { continue; }
|
||||
simconnectClouds += arg1s.arg(level, 3, 10, QLatin1Char('0')) %
|
||||
u'&';
|
||||
|
||||
// TT = Cloud type
|
||||
switch (cloudLayer.getClouds())
|
||||
{
|
||||
case CCloudLayer::Cirrus: simconnectClouds += QLatin1String("CI"); break;
|
||||
case CCloudLayer::Stratus: simconnectClouds += QLatin1String("ST"); break;
|
||||
case CCloudLayer::Thunderstorm: simconnectClouds += QLatin1String("CB"); break;
|
||||
case CCloudLayer::Cumulus:
|
||||
default:
|
||||
simconnectClouds += QLatin1String("CU");
|
||||
}
|
||||
|
||||
// 000 - Unused.
|
||||
simconnectClouds += QLatin1String("000");
|
||||
|
||||
// F = Top of cloud
|
||||
// Default to F - flat
|
||||
simconnectClouds += QLatin1Char('F');
|
||||
// T = Turbulence
|
||||
// N - None (default)
|
||||
simconnectClouds += QLatin1Char('N');
|
||||
|
||||
// P = precipitation rate
|
||||
// http://wiki.sandaysoft.com/a/Rain_measurement#Rain_Rate
|
||||
auto precipitationRate = cloudLayer.getPrecipitationRate();
|
||||
// Very light rain: precipitation rate is < 0.25 mm/hour
|
||||
if (precipitationRate < 0.25) { simconnectClouds += QLatin1Char('V'); }
|
||||
// Light rain: precipitation rate is between 0.25mm/hour and 1.0mm/hour
|
||||
else if (precipitationRate >= 0.25 && precipitationRate < 1.0) { simconnectClouds += QLatin1Char('L'); }
|
||||
// Moderate rain: precipitation rate is between 1.0 mm/hour and 4.0 mm/hour
|
||||
else if (precipitationRate >= 1.0 && precipitationRate < 4.0) { simconnectClouds += QLatin1Char('M'); }
|
||||
// Heavy rain: recipitation rate is between 4.0 mm/hour and 16.0 mm/hour
|
||||
else if (precipitationRate >= 4.0 && precipitationRate < 16.0) { simconnectClouds += QLatin1Char('H'); }
|
||||
// Very heavy rain: precipitation rate is > 16.0 mm/hour
|
||||
else if (precipitationRate >= 16.0) { simconnectClouds += QLatin1Char('D'); }
|
||||
|
||||
// Q = Type of precipitation
|
||||
switch (cloudLayer.getPrecipitation())
|
||||
{
|
||||
case CCloudLayer::Rain: simconnectClouds += QLatin1Char('R'); break;
|
||||
case CCloudLayer::Snow: simconnectClouds += QLatin1Char('S'); break;
|
||||
default: simconnectClouds += QLatin1Char('N');
|
||||
}
|
||||
|
||||
// BBB = Coded base height
|
||||
// the precipitation ends at this height, set to 0 for it to land on the ground
|
||||
simconnectClouds += QLatin1String("000");
|
||||
|
||||
// I = icing rate
|
||||
// Set to None for now
|
||||
simconnectClouds += QLatin1String("N");
|
||||
}
|
||||
return simconnectClouds;
|
||||
}
|
||||
|
||||
QString CSimConnectUtilities::temperaturesToSimConnectMetar(const CTemperatureLayerList &temperatureLayers)
|
||||
{
|
||||
// Format:
|
||||
// TT/DD&ANNNNN
|
||||
QString simconnectTemperatures;
|
||||
static const QString arg1s("%1");
|
||||
|
||||
for (const CTemperatureLayer &temperatureLayer : temperatureLayers)
|
||||
{
|
||||
simconnectTemperatures += QLatin1Char(' ');
|
||||
|
||||
const int temperature = temperatureLayer.getTemperature().valueInteger(CTemperatureUnit::C());
|
||||
const int dewPoint = temperatureLayer.getDewPoint().valueInteger(CTemperatureUnit::C());
|
||||
const int altitude = temperatureLayer.getLevel().valueInteger(CLengthUnit::m());
|
||||
|
||||
simconnectTemperatures += arg1s.arg(temperature, 2, 10, QLatin1Char('0')) % // TT = temperature in Celsius
|
||||
u'/' %
|
||||
arg1s.arg(dewPoint, 2, 10, QLatin1Char('0')) % // DD = dewpoint in Celsius
|
||||
u"&A" %
|
||||
arg1s.arg(altitude, 5, 10, QLatin1Char('0')); // NNNNN = altitude of the temperatures in meters.
|
||||
}
|
||||
return simconnectTemperatures;
|
||||
}
|
||||
|
||||
CWinDllUtils::DLLInfo CSimConnectUtilities::simConnectDllInfo()
|
||||
{
|
||||
const QList<CWinDllUtils::ProcessModule> modules = CWinDllUtils::getModules(-1, "simconnect");
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
|
||||
#include "blackmisc/simulation/simulatorinfo.h"
|
||||
#include "blackmisc/aviation/aircraftlights.h"
|
||||
#include "blackmisc/weather/gridpoint.h"
|
||||
#include "blackmisc/blackmiscexport.h"
|
||||
#include "blackmisc/windllutils.h"
|
||||
|
||||
@@ -227,9 +226,6 @@ namespace BlackMisc::Simulation::Fsx
|
||||
//! Lights to states
|
||||
static int lightsToLightStates(const Aviation::CAircraftLights &lights);
|
||||
|
||||
//! Converts the weather at gridPoint to a SimConnect METAR string
|
||||
static QString convertToSimConnectMetar(const Weather::CGridPoint &gridPoint, bool isFSX, bool useWindLayers = true, bool useVisibilityLayers = true, bool useCloudLayers = true, bool useTempLayers = true);
|
||||
|
||||
//! Get info about SimConnect DLL
|
||||
static BlackMisc::CWinDllUtils::DLLInfo simConnectDllInfo();
|
||||
|
||||
@@ -247,11 +243,6 @@ namespace BlackMisc::Simulation::Fsx
|
||||
//! \return enum element's name
|
||||
static QString resolveEnumToString(const DWORD id, const char *enumName);
|
||||
|
||||
static QString windsToSimConnectMetar(const BlackMisc::Weather::CWindLayerList &windLayers, bool isFSX);
|
||||
static QString visibilitiesToSimConnectMetar(const BlackMisc::Weather::CVisibilityLayerList &visibilityLayers);
|
||||
static QString cloudsToSimConnectMetar(const BlackMisc::Weather::CCloudLayerList &cloudLayers);
|
||||
static QString temperaturesToSimConnectMetar(const BlackMisc::Weather::CTemperatureLayerList &temperatureLayers);
|
||||
|
||||
//! Hidden constructor
|
||||
CSimConnectUtilities();
|
||||
};
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include "blackmisc/simulation/simulatedaircraft.h"
|
||||
#include "blackmisc/simulation/simulatorinfo.h"
|
||||
#include "blackmisc/network/textmessage.h"
|
||||
#include "blackmisc/weather/weatherscenario.h"
|
||||
#include "blackmisc/pq/length.h"
|
||||
#include "blackmisc/settingscache.h"
|
||||
#include "blackmisc/statusmessage.h"
|
||||
@@ -649,26 +648,6 @@ namespace BlackMisc::Simulation::Settings
|
||||
}
|
||||
};
|
||||
|
||||
//! Selected weather scenario
|
||||
struct TSelectedWeatherScenario : public TSettingTrait<Weather::CWeatherScenario>
|
||||
{
|
||||
//! \copydoc BlackMisc::TSettingTrait::key
|
||||
static const char *key() { return "simulator/selectedweatherscenario"; }
|
||||
|
||||
//! \copydoc BlackMisc::TSettingTrait::humanReadable
|
||||
static const QString &humanReadable()
|
||||
{
|
||||
static const QString name("Weather scenario");
|
||||
return name;
|
||||
}
|
||||
|
||||
//! \copydoc BlackMisc::TSettingTrait::defaultValue
|
||||
static const Weather::CWeatherScenario &defaultValue()
|
||||
{
|
||||
static const Weather::CWeatherScenario scenario {};
|
||||
return scenario;
|
||||
}
|
||||
};
|
||||
} // ns
|
||||
|
||||
Q_DECLARE_METATYPE(BlackMisc::Simulation::Settings::CSimulatorSettings)
|
||||
|
||||
Reference in New Issue
Block a user