refs #448 metar value classes

This commit is contained in:
Roland Winklmeier
2015-06-29 11:33:00 +00:00
committed by Mathew Sutcliffe
parent 047e408597
commit a94ea5618f
20 changed files with 1345 additions and 2 deletions

View File

@@ -37,7 +37,8 @@ HEADERS += *.h \
$$PWD/audio/*.h \ $$PWD/audio/*.h \
$$PWD/simulation/*.h \ $$PWD/simulation/*.h \
$$PWD/simulation/fscommon/*.h \ $$PWD/simulation/fscommon/*.h \
$$PWD/simulation/fsx/*.h $$PWD/simulation/fsx/*.h \
$$PWD/weather/*.h
SOURCES += *.cpp \ SOURCES += *.cpp \
$$PWD/pq/*.cpp \ $$PWD/pq/*.cpp \
@@ -49,7 +50,8 @@ SOURCES += *.cpp \
$$PWD/audio/*.cpp \ $$PWD/audio/*.cpp \
$$PWD/simulation/*.cpp \ $$PWD/simulation/*.cpp \
$$PWD/simulation/fscommon/*.cpp \ $$PWD/simulation/fscommon/*.cpp \
$$PWD/simulation/fsx/*.cpp $$PWD/simulation/fsx/*.cpp \
$$PWD/weather/*.cpp
DESTDIR = $$BuildRoot/lib DESTDIR = $$BuildRoot/lib
DLLDESTDIR = $$BuildRoot/bin DLLDESTDIR = $$BuildRoot/bin

View File

@@ -100,6 +100,7 @@ void BlackMisc::registerMetadata()
Audio::registerMetadata(); Audio::registerMetadata();
Hardware::registerMetadata(); Hardware::registerMetadata();
Event::registerMetadata(); Event::registerMetadata();
Weather::registerMetadata();
// needed by XBus proxy class // needed by XBus proxy class
qRegisterMetaType<CSequence<double>>(); qRegisterMetaType<CSequence<double>>();

View File

@@ -108,6 +108,12 @@ namespace BlackMisc
BLACKMISC_EXPORT void registerMetadata(); BLACKMISC_EXPORT void registerMetadata();
} }
namespace Weather
{
//! Register metadata for Simulation
BLACKMISC_EXPORT void registerMetadata();
}
//! Register all relevant metadata in BlackMisc //! Register all relevant metadata in BlackMisc
BLACKMISC_EXPORT void registerMetadata(); BLACKMISC_EXPORT void registerMetadata();

View File

@@ -65,6 +65,10 @@ namespace BlackMisc
GlobalIndexCAircraftIcaoCode = 2600, GlobalIndexCAircraftIcaoCode = 2600,
GlobalIndexCAirlineIcaoCode = 2700, GlobalIndexCAirlineIcaoCode = 2700,
GlobalIndexCAirportIcaoCode = 2800, GlobalIndexCAirportIcaoCode = 2800,
GlobalIndexCMetar = 2900,
GlobalIndexCCloudLayer = 2910,
GlobalIndexCPresentWeather = 2920,
GlobalIndexCWindLayer = 2930,
GlobalIndexICoordinateGeodetic = 3000, GlobalIndexICoordinateGeodetic = 3000,
GlobalIndexCCoordinateGeodetic = 3100, GlobalIndexCCoordinateGeodetic = 3100,
GlobalIndexCClient = 4000, GlobalIndexCClient = 4000,

View File

@@ -0,0 +1,28 @@
/* Copyright (C) 2015
* swift Project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
* including this file, may be copied, modified, propagated, or distributed except according to the terms
* contained in the LICENSE file.
*/
#include "blackmisc/blackmiscfreefunctions.h"
#include "blackmisc/weather/weather.h"
/*
* Metadata for aviation
*
* In a separate file to workaround a limitation of MinGW:
* http://stackoverflow.com/q/16596876/1639256
*/
void BlackMisc::Weather::registerMetadata()
{
CMetar::registerMetadata();
CMetarSet::registerMetadata();
CPresentWeather::registerMetadata();
CPresentWeatherList::registerMetadata();
CCloudLayer::registerMetadata();
CCloudLayerList::registerMetadata();
CWindLayer::registerMetadata();
}

View File

@@ -0,0 +1,77 @@
/* Copyright (C) 2015
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
* including this file, may be copied, modified, propagated, or distributed except according to the terms
* contained in the LICENSE file.
*/
#include "blackmisc/weather/cloudlayer.h"
#include "blackmisc/propertyindex.h"
#include "blackmisc/blackmiscfreefunctions.h"
#include "blackmisc/variant.h"
#include <tuple>
#include <QRegularExpression>
using namespace BlackMisc::Aviation;
namespace BlackMisc
{
namespace Weather
{
CCloudLayer::CCloudLayer(CAltitude ceiling, Coverage coverage) :
m_ceiling(ceiling), m_coverage(coverage)
{ }
CVariant CCloudLayer::propertyByIndex(const BlackMisc::CPropertyIndex &index) const
{
if (index.isMyself()) { return CVariant::from(*this); }
ColumnIndex i = index.frontCasted<ColumnIndex>();
switch (i)
{
case IndexCeiling:
return CVariant::fromValue(m_ceiling);
case IndexCoverage:
return CVariant::fromValue(m_coverage);
default:
return CValueObject::propertyByIndex(index);
}
}
void CCloudLayer::setPropertyByIndex(const CVariant &variant, const BlackMisc::CPropertyIndex &index)
{
if (index.isMyself()) { (*this) = variant.to<CCloudLayer>(); return; }
ColumnIndex i = index.frontCasted<ColumnIndex>();
switch (i)
{
case IndexCeiling:
setCeiling(variant.value<CAltitude>());
break;
case IndexCoverage:
setCoverage(variant.value<Coverage>());
break;
default:
CValueObject::setPropertyByIndex(variant, index);
break;
}
}
QString CCloudLayer::convertToQString(bool /** i18n **/) const
{
static const QHash<Coverage, QString> hash =
{
{ None, "" },
{ Few, "few" },
{ Scattered, "scattered" },
{ Broken, "broken" },
{ Overcast, "overcast" }
};
return QString("%1 in %2").arg(hash.value(m_coverage)).arg(m_ceiling.toQString());
}
} // namespace
} // namespace

View File

@@ -0,0 +1,91 @@
/* Copyright (C) 2015
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
* including this file, may be copied, modified, propagated, or distributed except according to the terms
* contained in the LICENSE file.
*/
//! \file
#ifndef BLACKMISC_WEATHER_CLOUDLAYER_H
#define BLACKMISC_WEATHER_CLOUDLAYER_H
#include "blackmisc/blackmiscexport.h"
#include "blackmisc/valueobject.h"
#include "blackmisc/propertyindex.h"
#include "blackmisc/blackmiscfreefunctions.h"
#include "blackmisc/aviation/altitude.h"
namespace BlackMisc
{
namespace Weather
{
/*!
* Value object for a cloud layer
*/
class BLACKMISC_EXPORT CCloudLayer : public CValueObject<CCloudLayer>
{
public:
//! Cloud coverage
enum Coverage
{
None,
Few,
Scattered,
Broken,
Overcast
};
//! Properties by index
enum ColumnIndex
{
IndexCloudLayer = BlackMisc::CPropertyIndex::GlobalIndexCCloudLayer,
IndexCeiling,
IndexCoverage
};
//! Default constructor.
CCloudLayer() = default;
//! Constructor
CCloudLayer(BlackMisc::Aviation::CAltitude ceiling, Coverage coverage);
//! Set ceiling
void setCeiling(BlackMisc::Aviation::CAltitude ceiling) { m_ceiling = ceiling; }
//! Get ceiling
BlackMisc::Aviation::CAltitude getCeiling() const { return m_ceiling; }
//! Set coverage
void setCoverage(Coverage coverage) { m_coverage = coverage; }
//! Get coverage
Coverage getCoverage() const { return m_coverage; }
//! \copydoc CValueObject::propertyByIndex
CVariant propertyByIndex(const BlackMisc::CPropertyIndex &index) const;
//! \copydoc CValueObject::setPropertyByIndex
void setPropertyByIndex(const CVariant &variant, const BlackMisc::CPropertyIndex &index);
//! \copydoc CValueObject::convertToQString
QString convertToQString(bool i18n = false) const;
private:
BLACK_ENABLE_TUPLE_CONVERSION(CCloudLayer)
BlackMisc::Aviation::CAltitude m_ceiling;
Coverage m_coverage;
};
} // namespace
} // namespace
Q_DECLARE_METATYPE(BlackMisc::Weather::CCloudLayer)
Q_DECLARE_METATYPE(BlackMisc::Weather::CCloudLayer::Coverage)
BLACK_DECLARE_TUPLE_CONVERSION(BlackMisc::Weather::CCloudLayer, (
attr(o.m_ceiling),
attr(o.m_coverage)
))
#endif // guard

View File

@@ -0,0 +1,33 @@
/* Copyright (C) 2015
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
* including this file, may be copied, modified, propagated, or distributed except according to the terms
* contained in the LICENSE file.
*/
#include "cloudlayerlist.h"
using namespace BlackMisc::Aviation;
namespace BlackMisc
{
namespace Weather
{
CCloudLayerList::CCloudLayerList(const CSequence<CCloudLayer> &other) :
CSequence<CCloudLayer>(other)
{ }
bool CCloudLayerList::containsCeiling(const CAltitude &ceiling) const
{
return contains(&CCloudLayer::getCeiling, ceiling);
}
CCloudLayer CCloudLayerList::findByCeiling(const CAltitude &ceiling) const
{
return findFirstByOrDefault(&CCloudLayer::getCeiling, ceiling);
}
} // namespace
} // namespace

View File

@@ -0,0 +1,52 @@
/* Copyright (C) 2015
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
* including this file, may be copied, modified, propagated, or distributed except according to the terms
* contained in the LICENSE file.
*/
//! \file
#ifndef BLACKMISC_WEATHER_CLOUDLAYERLIST_H
#define BLACKMISC_WEATHER_CLOUDLAYERLIST_H
#include "cloudlayer.h"
#include "blackmisc/blackmiscexport.h"
#include "blackmisc/sequence.h"
namespace BlackMisc
{
namespace Weather
{
/*!
* Value object encapsulating a set of cloud layers
*/
class BLACKMISC_EXPORT CCloudLayerList :
public CSequence<CCloudLayer>,
public BlackMisc::Mixin::MetaType<CCloudLayerList>
{
public:
BLACKMISC_DECLARE_USING_MIXIN_METATYPE(CCloudLayerList)
//! Default constructor.
CCloudLayerList() = default;
//! Construct from a base class object.
CCloudLayerList(const CSequence<CCloudLayer> &other);
//! Contains cloud layer with ceiling?
bool containsCeiling(const BlackMisc::Aviation::CAltitude &ceiling) const;
//! Find cloud layer by ceiling
CCloudLayer findByCeiling(const BlackMisc::Aviation::CAltitude &ceiling) const;
};
} //namespace
} // namespace
Q_DECLARE_METATYPE(BlackMisc::Weather::CCloudLayerList)
Q_DECLARE_METATYPE(BlackMisc::CSequence<BlackMisc::Weather::CCloudLayer>)
#endif //guard

View File

@@ -0,0 +1,207 @@
/* Copyright (C) 2015
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
* including this file, may be copied, modified, propagated, or distributed except according to the terms
* contained in the LICENSE file.
*/
#include "metar.h"
#include "blackmiscfreefunctions.h"
using namespace BlackMisc::PhysicalQuantities;
using namespace BlackMisc::Aviation;
namespace BlackMisc
{
namespace Weather
{
CMetar::CMetar()
{
setCavok();
}
void CMetar::setMessage(const QString &message)
{
m_metarMessage = message;
}
QString CMetar::getMessage() const
{
return m_metarMessage;
}
void CMetar::setReportType(ReportType type)
{
m_reportType = type;
}
CMetar::ReportType CMetar::getReportType() const
{
return m_reportType;
}
void CMetar::setAirportIcaoCode(const CAirportIcaoCode &icao)
{
m_airport = icao;
}
CAirportIcaoCode CMetar::getAirportIcaoCode() const
{
return m_airport;
}
void CMetar::setDayTime(int reportDay, const PhysicalQuantities::CTime &reportTime)
{
m_reportDay = reportDay; m_reportTime = reportTime;
}
int CMetar::getDay() const
{
return m_reportDay;
}
PhysicalQuantities::CTime CMetar::getTime() const
{
return m_reportTime;
}
void CMetar::setAutomated(bool isAutomated)
{
m_isAutomated = isAutomated;
}
void CMetar::setCavok()
{
m_visibility = CLength(10000, CLengthUnit::km());
m_presentWeathers.clear();
m_cloudLayers.clear();
}
bool CMetar::isCavok() const
{
return false;
}
void CMetar::setWindLayer(const CWindLayer &windLayer)
{
m_windLayer = windLayer;
}
CWindLayer CMetar::getWindLayer() const
{
return m_windLayer;
}
void CMetar::setVisibility(const PhysicalQuantities::CLength &visibility)
{
m_visibility = visibility;
}
PhysicalQuantities::CLength CMetar::getVisibility() const
{
return m_visibility;
}
void CMetar::addPresentWeather(const CPresentWeather &presentWeather)
{
m_presentWeathers.push_back(presentWeather);
}
CPresentWeatherList CMetar::getPresentWeather() const
{
return m_presentWeathers;
}
void CMetar::addCloudLayer(const CCloudLayer &cloudLayer)
{
m_cloudLayers.push_back(cloudLayer);
}
CCloudLayerList CMetar::getCloudLayers() const
{
return m_cloudLayers;
}
void CMetar::setTemperature(const PhysicalQuantities::CTemperature &temperature)
{
m_temperature = temperature;
}
PhysicalQuantities::CTemperature CMetar::getTemperature() const
{
return m_temperature;
}
void CMetar::setDewPoint(const PhysicalQuantities::CTemperature &dewPoint)
{
m_dewPoint = dewPoint;
}
PhysicalQuantities::CTemperature CMetar::getDewPoint() const
{
return m_dewPoint;
}
void CMetar::setAltimeter(const PhysicalQuantities::CPressure &altimeter)
{
m_altimeter = altimeter;
}
PhysicalQuantities::CPressure CMetar::getAltimeter() const
{
return m_altimeter;
}
QString CMetar::getMetarText() const
{
QString metarDescription;
metarDescription += QString("Station: %1 \n").arg(m_airport.getIcaoCode());
metarDescription += QString("Date/Time: %1 %2 UTC\n").arg(m_reportDay).arg(m_reportTime.formattedHrsMin());
metarDescription += m_windLayer.toQString();
metarDescription += "\n";
metarDescription += QString("Visibility: %1\n").arg(m_visibility.toQString());
metarDescription += QString("Weather: ");
QString presentWeathers;
for (const auto &presentWeather : m_presentWeathers)
{
if (!presentWeathers.isEmpty()) presentWeathers += ",";
presentWeathers += " ";
presentWeathers += presentWeather.toQString();
}
metarDescription += presentWeathers.simplified();
metarDescription += QString("\n");
metarDescription += QString("Clouds:");
QString clouds;
for (const auto &layer : m_cloudLayers)
{
if (!clouds.isEmpty()) clouds += ",";
clouds += " ";
clouds += layer.toQString();
}
metarDescription += clouds;
metarDescription += QString("\n");
metarDescription += QString("Temperature: %1\n").arg(m_temperature.toQString());
metarDescription += QString("Dewpoint: %1\n").arg(m_dewPoint.toQString());
metarDescription += QString("Altimeter: %1\n").arg(m_altimeter.toQString());
return metarDescription;
}
QString CMetar::convertToQString(bool i18n) const
{
Q_UNUSED(i18n);
QString s(m_airport.getIcaoCode());
return s;
}
CMetar CMetar::CAVOK()
{
CMetar metar;
metar.setCavok();
return metar;
}
} // namespace
} // namespace

View File

@@ -0,0 +1,178 @@
/* Copyright (C) 2015
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
* including this file, may be copied, modified, propagated, or distributed except according to the terms
* contained in the LICENSE file.
*/
//! \file
#ifndef BLACKMISC_AVIATION_METAR_H
#define BLACKMISC_AVIATION_METAR_H
#include "blackmisc/blackmiscexport.h"
#include "blackmisc/valueobject.h"
#include "blackmisc/aviation/airporticaocode.h"
#include "blackmisc/weather/cloudlayerlist.h"
#include "blackmisc/weather/presentweatherlist.h"
#include "blackmisc/weather/windlayer.h"
#include "blackmisc/pq/time.h"
#include "blackmisc/pq/length.h"
#include "blackmisc/pq/temperature.h"
#include "blackmisc/pq/pressure.h"
namespace BlackMisc
{
namespace Weather
{
/*!
* Value object encapsulating information about METAR
* FIXME: runway visibilities
* FIXME: runway wind shear
* FIXME: remarks
*/
class BLACKMISC_EXPORT CMetar : public CValueObject<CMetar>
{
public:
//! Report type
enum ReportType
{
METAR,
SPECI
};
//! Default constructor
CMetar();
//! Set METAR message
void setMessage(const QString &message);
//! Get METAR message
QString getMessage() const;
//! Set report type
void setReportType(ReportType type);
//! Get report type
ReportType getReportType() const;
//! Set airport icao code
void setAirportIcaoCode(const BlackMisc::Aviation::CAirportIcaoCode &icao);
//! Get airport icao code
BlackMisc::Aviation::CAirportIcaoCode getAirportIcaoCode() const;
//! Set day and time
void setDayTime(int reportDay, const PhysicalQuantities::CTime &reportTime);
//! Get report day
int getDay() const;
//! Get report time
PhysicalQuantities::CTime getTime() const;
//! Set the station to automated
void setAutomated(bool isAutomated);
//! Is the station automated?
bool isAutomated() const { return m_isAutomated; }
//! Set the weather to CAVOK
void setCavok();
//! Is CAVOK?
bool isCavok() const;
//! Set wind information
void setWindLayer(const CWindLayer &windLayer);
//! Get wind layer
CWindLayer getWindLayer() const;
//! Set visibility information
void setVisibility(const PhysicalQuantities::CLength &visibility);
//! Get visibility
PhysicalQuantities::CLength getVisibility() const;
//! Add information about present weather
void addPresentWeather(const CPresentWeather &presentWeather);
//! Get present weather list
CPresentWeatherList getPresentWeather() const;
//! Add cloud layer
void addCloudLayer(const CCloudLayer &cloudLayer);
//! Get all cloud layers
CCloudLayerList getCloudLayers() const;
//! Remove all cloud layers
void removeAllClouds() { m_cloudLayers.clear(); }
//! Set temperature
void setTemperature(const PhysicalQuantities::CTemperature &temperature);
//! Get temperature
PhysicalQuantities::CTemperature getTemperature() const;
//! Set dew point
void setDewPoint(const PhysicalQuantities::CTemperature &dewPoint);
//! Get dew point
PhysicalQuantities::CTemperature getDewPoint() const;
//! Set altimeter
void setAltimeter(const PhysicalQuantities::CPressure &altimeter);
//! Get altimeter
PhysicalQuantities::CPressure getAltimeter() const;
//! Returns the metar in a descriptive text
QString getMetarText() const;
//! \copydoc CValueObject::convertToQString
QString convertToQString(bool i18n = false) const;
//! Return CAVOK metar
static CMetar CAVOK();
private:
BLACK_ENABLE_TUPLE_CONVERSION(CMetar)
QString m_metarMessage;
ReportType m_reportType = METAR;
BlackMisc::Aviation::CAirportIcaoCode m_airport;
int m_reportDay = 0;
PhysicalQuantities::CTime m_reportTime;
bool m_isAutomated = false;
CWindLayer m_windLayer;
PhysicalQuantities::CLength m_visibility;
CPresentWeatherList m_presentWeathers;
CCloudLayerList m_cloudLayers;
PhysicalQuantities::CTemperature m_temperature;
PhysicalQuantities::CTemperature m_dewPoint;
PhysicalQuantities::CPressure m_altimeter;
};
} // namespace
} // namespace
Q_DECLARE_METATYPE(BlackMisc::Weather::CMetar)
BLACK_DECLARE_TUPLE_CONVERSION(BlackMisc::Weather::CMetar, (
attr(o.m_metarMessage),
attr(o.m_reportType),
attr(o.m_airport),
attr(o.m_reportDay),
attr(o.m_reportTime),
attr(o.m_isAutomated),
attr(o.m_windLayer),
attr(o.m_visibility),
attr(o.m_presentWeathers),
attr(o.m_cloudLayers),
attr(o.m_temperature),
attr(o.m_dewPoint),
attr(o.m_altimeter)
))
#endif // guard

View File

@@ -0,0 +1,21 @@
/* Copyright (C) 2015
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
* including this file, may be copied, modified, propagated, or distributed except according to the terms
* contained in the LICENSE file.
*/
#include "metarset.h"
namespace BlackMisc
{
namespace Weather
{
CMetarSet::CMetarSet(const CCollection<CMetar> &other) :
CCollection<CMetar>(other)
{ }
} // namespace
} // namespace

View File

@@ -0,0 +1,46 @@
/* Copyright (C) 2015
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
* including this file, may be copied, modified, propagated, or distributed except according to the terms
* contained in the LICENSE file.
*/
//! \file
#ifndef BLACKMISC_WEATHER_METARSET_H
#define BLACKMISC_WEATHER_METARSET_H
#include "blackmisc/blackmiscexport.h"
#include "blackmisc/weather/metar.h"
#include "blackmisc/collection.h"
#include "blackmisc/sequence.h"
namespace BlackMisc
{
namespace Weather
{
//! Collection of Metars
class BLACKMISC_EXPORT CMetarSet :
public CCollection<CMetar>,
public BlackMisc::Mixin::MetaType<CMetarSet>
{
public:
BLACKMISC_DECLARE_USING_MIXIN_METATYPE(CMetarSet)
//! Default constructor.
CMetarSet() = default;
//! Construct from a base class object.
CMetarSet(const CCollection<CMetar> &other);
};
} //namespace
} // namespace
Q_DECLARE_METATYPE(BlackMisc::Weather::CMetarSet)
Q_DECLARE_METATYPE(BlackMisc::CCollection<BlackMisc::Weather::CMetar>)
Q_DECLARE_METATYPE(BlackMisc::CSequence<BlackMisc::Weather::CMetar>)
#endif //guard

View File

@@ -0,0 +1,131 @@
/* Copyright (C) 2015
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
* including this file, may be copied, modified, propagated, or distributed except according to the terms
* contained in the LICENSE file.
*/
#include "blackmisc/weather/presentweather.h"
#include "blackmisc/propertyindex.h"
#include "blackmisc/blackmiscfreefunctions.h"
#include "blackmisc/variant.h"
namespace BlackMisc
{
namespace Weather
{
CPresentWeather::CPresentWeather(Intensity intensity, Descriptor descriptor, int weatherPhenomena) :
m_intensity(intensity), m_descriptor(descriptor), m_weatherPhenomena(weatherPhenomena)
{ }
CVariant CPresentWeather::propertyByIndex(const BlackMisc::CPropertyIndex &index) const
{
if (index.isMyself()) { return CVariant::from(*this); }
ColumnIndex i = index.frontCasted<ColumnIndex>();
switch (i)
{
case IndexIntensity:
return CVariant::fromValue<int>(static_cast<int>(m_intensity));
case IndexDescriptor:
return CVariant::fromValue<int>(static_cast<int>(m_descriptor));
case IndexWeatherPhenomena:
return CVariant::fromValue(m_weatherPhenomena);
default:
return CValueObject::propertyByIndex(index);
}
}
void CPresentWeather::setPropertyByIndex(const CVariant &variant, const BlackMisc::CPropertyIndex &index)
{
if (index.isMyself()) { (*this) = variant.to<CPresentWeather>(); return; }
ColumnIndex i = index.frontCasted<ColumnIndex>();
switch (i)
{
case IndexIntensity:
setIntensity(static_cast<Intensity>(variant.toInt()));
break;
case IndexDescriptor:
setDescriptor(static_cast<Descriptor>(variant.toInt()));
break;
case IndexWeatherPhenomena:
setWeatherPhenomena(variant.toInt());
break;
default:
CValueObject::setPropertyByIndex(variant, index);
break;
}
}
QString CPresentWeather::convertToQString(bool /** i18n **/) const
{
static const QHash<Intensity, QString> intensityHash =
{
{ Moderate, "moderate" },
{ Light, "light" },
{ Heavy, "heavy" },
{ InVincinity, "in vincinity" },
};
static const QHash<Descriptor, QString> descriptorHash =
{
{ None, "" },
{ Shallow, "shallow" },
{ Patches, "patches" },
{ Partial, "partial" },
{ Drifting, "drifting" },
{ Blowing, "blowing" },
{ Showers, "showers" },
{ Thunderstorm, "thunderstorm" },
{ Freezing, "freezing" },
};
static const QHash<WeatherPhenomenon, QString> weatherPhenomenaHash =
{
{ Drizzle, "drizzle" },
{ Rain, "rain" },
{ Snow, "snow" },
{ SnowGrains, "snow srains" },
{ IceCrystals, "ice crystals" },
{ IcePellets, "ice pellets" },
{ Hail, "hail" },
{ SnowPellets, "snow pellets" },
{ Unknown, "unknown" },
{ Mist, "mist" },
{ Fog, "fog" },
{ Smoke, "smoke" },
{ VolcanicAsh, "volcanic ash" },
{ Dust, "dust" },
{ Sand, "sand" },
{ Haze, "haze" },
{ DustSandWhirls, "dustSand whirls" },
{ Squalls, "squalls" },
{ TornadoOrWaterspout, "tornado or waterspout" },
{ FunnelCloud, "funnel cloud" },
{ Sandstorm, "sandstorm" },
{ Duststorm, "duststorm" }
};
QString weatherPhenomenaAsString;
for (const auto &wp : weatherPhenomenaHash.keys())
{
if (m_weatherPhenomena & wp)
{
if (!weatherPhenomenaAsString.isEmpty()) weatherPhenomenaAsString += " and ";
weatherPhenomenaAsString += weatherPhenomenaHash.value(wp);
}
}
QString str;
str += intensityHash.value(m_intensity);
str += " ";
str += descriptorHash.value(m_descriptor);
str += " ";
str += weatherPhenomenaAsString;
return str;
}
} // namespace
} // namespace

View File

@@ -0,0 +1,141 @@
/* Copyright (C) 2015
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
* including this file, may be copied, modified, propagated, or distributed except according to the terms
* contained in the LICENSE file.
*/
//! \file
#ifndef BLACKMISC_WEATHER_PRESENTWEATHER_H
#define BLACKMISC_WEATHER_PRESENTWEATHER_H
#include "blackmisc/blackmiscexport.h"
#include "blackmisc/valueobject.h"
#include "blackmisc/propertyindex.h"
#include "blackmisc/blackmiscfreefunctions.h"
#include <type_traits>
namespace BlackMisc
{
namespace Weather
{
/*!
* Value object for a cloud layer
*/
class BLACKMISC_EXPORT CPresentWeather : public CValueObject<CPresentWeather>
{
public:
//! Intensity
enum Intensity
{
Light,
Moderate,
Heavy,
InVincinity
};
//! Descriptor
enum Descriptor
{
None,
Shallow,
Patches,
Partial,
Drifting,
Blowing,
Showers,
Thunderstorm,
Freezing,
};
//! Weather Phenomenon
enum WeatherPhenomenon
{
NoPhenomena = 0,
Drizzle = 1 << 0,
Rain = 1 << 1,
Snow = 1 << 2,
SnowGrains = 1 << 3,
IceCrystals = 1 << 4,
IcePellets = 1 << 5,
Hail = 1 << 6,
SnowPellets = 1 << 7,
Unknown = 1 << 8,
Mist = 1 << 9,
Fog = 1 << 10,
Smoke = 1 << 11,
VolcanicAsh = 1 << 12,
Dust = 1 << 13,
Sand = 1 << 14,
Haze = 1 << 15,
DustSandWhirls = 1 << 16,
Squalls = 1 << 17,
TornadoOrWaterspout = 1 << 18,
FunnelCloud = 1 << 19,
Sandstorm = 1 << 20,
Duststorm = 1 << 21,
};
//! Properties by index
enum ColumnIndex
{
IndexPresentWeather = BlackMisc::CPropertyIndex::GlobalIndexCPresentWeather,
IndexIntensity,
IndexDescriptor,
IndexWeatherPhenomena
};
//! Default constructor.
CPresentWeather() = default;
//! Constructor
CPresentWeather(Intensity intensity, Descriptor descriptor, int weatherPhenomena);
//! Set intensity
void setIntensity(Intensity intensity) { m_intensity = intensity; }
//! Get intensity
Intensity getIntensity() const { return m_intensity; }
//! Set descriptor
void setDescriptor(Descriptor descriptor) { m_descriptor = descriptor; }
//! Get descriptor
Descriptor getDescriptor() const { return m_descriptor; }
//! Set weather phenomena
void setWeatherPhenomena(int phenomena) { m_weatherPhenomena = phenomena; }
//! Get weather phenomenas
int getWeatherPhenomena() const { return m_weatherPhenomena; }
//! \copydoc CValueObject::propertyByIndex
CVariant propertyByIndex(const BlackMisc::CPropertyIndex &index) const;
//! \copydoc CValueObject::setPropertyByIndex
void setPropertyByIndex(const CVariant &variant, const BlackMisc::CPropertyIndex &index);
//! \copydoc CValueObject::convertToQString
QString convertToQString(bool i18n = false) const;
private:
BLACK_ENABLE_TUPLE_CONVERSION(CPresentWeather)
Intensity m_intensity = Moderate;
Descriptor m_descriptor = None;
int m_weatherPhenomena;
};
} // namespace
} // namespace
Q_DECLARE_METATYPE(BlackMisc::Weather::CPresentWeather)
BLACK_DECLARE_TUPLE_CONVERSION(BlackMisc::Weather::CPresentWeather, (
attr(o.m_intensity),
attr(o.m_descriptor),
attr(o.m_weatherPhenomena)
))
#endif // guard

View File

@@ -0,0 +1,21 @@
/* Copyright (C) 2015
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
* including this file, may be copied, modified, propagated, or distributed except according to the terms
* contained in the LICENSE file.
*/
#include "presentweatherlist.h"
namespace BlackMisc
{
namespace Weather
{
CPresentWeatherList::CPresentWeatherList(const CSequence<CPresentWeather> &other) :
CSequence<CPresentWeather>(other)
{ }
} // namespace
} // namespace

View File

@@ -0,0 +1,46 @@
/* Copyright (C) 2015
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
* including this file, may be copied, modified, propagated, or distributed except according to the terms
* contained in the LICENSE file.
*/
//! \file
#ifndef BLACKMISC_WEATHER_PRESENTWEATHERLIST_H
#define BLACKMISC_WEATHER_PRESENTWEATHERLIST_H
#include "presentweather.h"
#include "blackmisc/blackmiscexport.h"
#include "blackmisc/sequence.h"
namespace BlackMisc
{
namespace Weather
{
/*!
* Value object encapsulating a list of present weathers
*/
class BLACKMISC_EXPORT CPresentWeatherList :
public CSequence<CPresentWeather>,
public BlackMisc::Mixin::MetaType<CPresentWeatherList>
{
public:
BLACKMISC_DECLARE_USING_MIXIN_METATYPE(CPresentWeatherList)
//! Default constructor.
CPresentWeatherList() = default;
//! Construct from a base class object.
CPresentWeatherList(const CSequence<CPresentWeather> &other);
};
} //namespace
} // namespace
Q_DECLARE_METATYPE(BlackMisc::Weather::CPresentWeatherList)
Q_DECLARE_METATYPE(BlackMisc::CSequence<BlackMisc::Weather::CPresentWeather>)
#endif //guard

View File

@@ -0,0 +1,28 @@
/* Copyright (C) 2015
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
* including this file, may be copied, modified, propagated, or distributed except according to the terms
* contained in the LICENSE file.
*/
//! \file
#ifndef BLACKMISC_wEATHER_wEATHER_H
#define BLACKMISC_wEATHER_wEATHER_H
/*!
* \namespace BlackMisc::Weather
* \brief Weather and Metar classes
*/
#include "blackmisc/weather/metar.h"
#include "blackmisc/weather/metarset.h"
#include "blackmisc/weather/presentweather.h"
#include "blackmisc/weather/presentweatherlist.h"
#include "blackmisc/weather/cloudlayer.h"
#include "blackmisc/weather/cloudlayerlist.h"
#include "blackmisc/weather/windlayer.h"
#endif // guard

View File

@@ -0,0 +1,92 @@
/* Copyright (C) 2015
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
* including this file, may be copied, modified, propagated, or distributed except according to the terms
* contained in the LICENSE file.
*/
#include "blackmisc/weather/windlayer.h"
#include "blackmisc/propertyindex.h"
#include "blackmisc/blackmiscfreefunctions.h"
#include "blackmisc/variant.h"
using namespace BlackMisc::PhysicalQuantities;
using namespace BlackMisc::Aviation;
namespace BlackMisc
{
namespace Weather
{
CWindLayer::CWindLayer(const CAltitude &altitude, const CAngle &direction, const CSpeed &speed, const CSpeed &gustSpeed) :
m_altitude(altitude), m_directionMain(direction), m_speed(speed), m_gustSpeed(gustSpeed)
{ }
CVariant CWindLayer::propertyByIndex(const BlackMisc::CPropertyIndex &index) const
{
if (index.isMyself()) { return CVariant::from(*this); }
ColumnIndex i = index.frontCasted<ColumnIndex>();
switch (i)
{
case IndexAltitude:
return CVariant::fromValue(m_altitude);
case IndexDirection:
return CVariant::fromValue(m_directionMain);
case IndexDirectionVariable:
return CVariant::fromValue(m_directionVariable);
case IndexSpeed:
return CVariant::fromValue(m_speed);
case IndexGustSpeed:
return CVariant::fromValue(m_gustSpeed);
default:
return CValueObject::propertyByIndex(index);
}
}
void CWindLayer::setPropertyByIndex(const CVariant &variant, const BlackMisc::CPropertyIndex &index)
{
if (index.isMyself()) { (*this) = variant.to<CWindLayer>(); return; }
ColumnIndex i = index.frontCasted<ColumnIndex>();
switch (i)
{
case IndexAltitude:
setAltitude(variant.value<CAltitude>());
break;
case IndexDirection:
setDirection(variant.value<CAngle>());
break;
case IndexDirectionVariable:
setDirectionVariable(variant.toBool());
break;
case IndexSpeed:
setSpeed(variant.value<CSpeed>());
break;
case IndexGustSpeed:
setGustSpeed(variant.value<CSpeed>());
break;
default:
CValueObject::setPropertyByIndex(variant, index);
break;
}
}
QString CWindLayer::convertToQString(bool /** i18n **/) const
{
QString windAsString = QString("Wind: ");
if (m_directionVariable) windAsString += "variable ";
else windAsString += QString("%1 ").arg(m_directionMain.toQString());
if (m_directionFrom != CAngle() && m_directionTo != CAngle())
{
windAsString += QString("variable between %1 and %2 ").arg(m_directionFrom.toQString()).arg(m_directionTo.toQString());
}
windAsString += QString("at %2").arg(m_speed.toQString());
if (m_gustSpeed.value() > 0.5) windAsString += QString(" and gusts at %1").arg(m_gustSpeed.toQString());
return windAsString;
}
} // namespace
} // namespace

View File

@@ -0,0 +1,138 @@
/* Copyright (C) 2015
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
* including this file, may be copied, modified, propagated, or distributed except according to the terms
* contained in the LICENSE file.
*/
//! \file
#ifndef BLACKMISC_WEATHER_WINDLAYER_H
#define BLACKMISC_WEATHER_WINDLAYER_H
#include "blackmisc/blackmiscexport.h"
#include "blackmisc/valueobject.h"
#include "blackmisc/propertyindex.h"
#include "blackmisc/blackmiscfreefunctions.h"
#include "blackmisc/pq/angle.h"
#include "blackmisc/pq/speed.h"
#include "blackmisc/aviation/altitude.h"
#include <type_traits>
namespace BlackMisc
{
namespace Weather
{
/*!
* Value object for a wind layer
*/
class BLACKMISC_EXPORT CWindLayer : public CValueObject<CWindLayer>
{
public:
//! Properties by index
enum ColumnIndex
{
IndexAltitude = BlackMisc::CPropertyIndex::GlobalIndexCWindLayer,
IndexDirection,
IndexDirectionVariable,
IndexSpeed,
IndexGustSpeed
};
//! Default constructor.
CWindLayer() = default;
//! Constructor
CWindLayer(const BlackMisc::Aviation::CAltitude &altitude, const PhysicalQuantities::CAngle &direction,
const PhysicalQuantities::CSpeed &speed, const PhysicalQuantities::CSpeed &gustSpeed);
//! Set altitude
void setAltitude(const BlackMisc::Aviation::CAltitude &altitude) { m_altitude = altitude; }
//! Get altitude
BlackMisc::Aviation::CAltitude getAltitude() const { return m_altitude; }
//! Set direction
void setDirection(const PhysicalQuantities::CAngle &main) { m_directionMain = main; }
//! Set direction
//! Main direction will not be modified
void setDirection(const PhysicalQuantities::CAngle &from, const PhysicalQuantities::CAngle &to)
{
m_directionFrom = from;
m_directionTo = to;
}
//! Set direction
void setDirection(const PhysicalQuantities::CAngle &main, const PhysicalQuantities::CAngle &from, const PhysicalQuantities::CAngle &to)
{
m_directionMain = main;
m_directionFrom = from;
m_directionTo = to;
}
//! Get direction
PhysicalQuantities::CAngle getDirection() const { return m_directionMain; }
//! Get direction from
PhysicalQuantities::CAngle getDirectionFrom() const { return m_directionFrom; }
//! Get direction to
PhysicalQuantities::CAngle getDirectionTo() const { return m_directionTo; }
//! Set direction to variable
void setDirectionVariable(bool variable = true) { m_directionVariable = variable; }
//! Is direction variable?
bool isDirectionVariable() const { return m_directionVariable; }
//! Set speed
void setSpeed(const PhysicalQuantities::CSpeed &speed) { m_speed = speed; }
//! Get descriptor
PhysicalQuantities::CSpeed getSpeed() const { return m_speed; }
//! Set gust speed
void setGustSpeed(const PhysicalQuantities::CSpeed &gustSpeed) { m_gustSpeed = gustSpeed; }
//! Get weather phenomenas
PhysicalQuantities::CSpeed getGustSpeed() const { return m_gustSpeed; }
//! \copydoc CValueObject::propertyByIndex
CVariant propertyByIndex(const BlackMisc::CPropertyIndex &index) const;
//! \copydoc CValueObject::setPropertyByIndex
void setPropertyByIndex(const CVariant &variant, const BlackMisc::CPropertyIndex &index);
//! \copydoc CValueObject::convertToQString
QString convertToQString(bool i18n = false) const;
private:
BLACK_ENABLE_TUPLE_CONVERSION(CWindLayer)
BlackMisc::Aviation::CAltitude m_altitude;
PhysicalQuantities::CAngle m_directionMain;
PhysicalQuantities::CAngle m_directionFrom;
PhysicalQuantities::CAngle m_directionTo;
bool m_directionVariable = false;
PhysicalQuantities::CSpeed m_speed;
PhysicalQuantities::CSpeed m_gustSpeed;
};
} // namespace
} // namespace
Q_DECLARE_METATYPE(BlackMisc::Weather::CWindLayer)
BLACK_DECLARE_TUPLE_CONVERSION(BlackMisc::Weather::CWindLayer, (
attr(o.m_altitude),
attr(o.m_directionMain),
attr(o.m_directionFrom),
attr(o.m_directionTo),
attr(o.m_directionVariable),
attr(o.m_speed),
attr(o.m_gustSpeed)
))
#endif // guard