NavDataExplorer/navigationdata.h
2025-07-11 21:48:37 +02:00

638 lines
14 KiB
C++

#pragma once
#include <boost/shared_ptr.hpp>
#include <vector>
#include <algorithm>
#ifndef _USE_MATH_DEFINES
#define _USE_MATH_DEFINES
#endif
#include <math.h>
#include "latitudelongitude.fs.h"
//#include <cereal/types/polymorphic.hpp>
//#include <cereal/types/base_class.hpp>
#define ALT_INVALID -9999
#define SPD_INVALID -1
#define HDG_INVALID -1
#define DIST_INVALID -1
#define TEMP_INVALID -999
#define KMTONM(km) (km * 0.539957)
#define NMTOKM(nm) (nm * 1.852)
class Winds
{
public:
double alt = ALT_INVALID;
double speed = SPD_INVALID;
double direction = HDG_INVALID;
bool isManual = false;
static Winds Interpolate(std::vector<Winds> winds, double altitude);
bool IsValid() const;
template <class B> void store(B& buf) const;
template <class B> void parse(B& buf);
};
enum class TrackCode
{
ArcToFix, //AF
CourseToAltitude, //CA
CourseToDMEDistance, //CD
CourseToFix, //CF
CourseToNextIntercept, //CI
CourseToRadialTermination, //CR
DirectToFix, //DF
CourseFromFixToAltitude, //FA
CourseFromFixToDMEDistance, //FD
CourseFromFixToManualTermination, //FM
TrackFromFixToDistance, //FC
HoldToAltitude, //HA
HoldAtFix, //HF
HoldUntilManualTermination, //HM
InitialFix, //IF
ProcedureTurnToIntercept, //PI
RadiusToFix, //RF
TrackToFix, //TF
HeadingToAltitude, //VA
HeadingToDMEDistance, //VD
HeadingToNextLegIntercept, //VI
HeadingUntilManualTermination, //VM
HeadingToRadialTermination, //VR
};
enum class NavDataObjType
{
Indeterminate,
TerminalLeg,
Waypoint,
Navaid,
AirwayLeg,
Airport,
Discontinuity,
Runway,
LatitudeLongitude,
PilotDefinedWaypoint,
Hold
};
enum class AirwayStatus
{
Incomplete,
OK
};
enum class TurnDirection
{
Left,
Right
};
enum class ObjectTurnDirection
{
Left = -1,
Unspecified = 0,
Right = 1
};
enum class ObjectUsagePhase
{
Unknown,
Climb,
Descent,
MissedApproach
};
enum class ObjectUsage
{
Leg,
InitialPosition,
Origin,
DepartureLeg,
ArrivalLeg,
ApproachLeg,
Destination,
TurnPoint,
ToC,
ToD,
SC
};
enum class AltitudeRestrictionType
{
Above,
Below,
Between,
Exact,
Step,
Unspecified
};
struct LateralSegment
{
LatitudeLongitude startPoint;
LatitudeLongitude endPoint;
double turnRadius = 0;
double turnStartRadial = 0;
double turnEndRadial = 0;
LatitudeLongitude turnCenterPoint;
TurnDirection turnDir = TurnDirection::Left;
bool afsComplete = false;
LateralSegment() {}
LateralSegment(LatitudeLongitude start, LatitudeLongitude end);
LateralSegment(LatitudeLongitude center, LatitudeLongitude start, LatitudeLongitude end, TurnDirection direction);
double GetLength();
//may need ground distance, vertical rate, delta altitude, etc.
//use performance recording/monitoring software to sample data points from testers to build perf DB
template <class B> void store(B& buf) const;
template <class B> void parse(B& buf);
};
struct VerticalSegment
{
double endsAt = 1.0;
double speed = SPD_INVALID;
double altitude = ALT_INVALID;
double speedRestriction = SPD_INVALID;
ObjectUsagePhase phase = ObjectUsagePhase::Unknown;
//DEBUG
double fpm = 0;
double distToArr = 0;
double gs = 0;
//
double fuelBurned = 0;
VerticalSegment() {}
VerticalSegment(double endsAt, double speed, double altitude, double speedRestriction, ObjectUsagePhase usagePhase, double FPM = 0, double DTA = 0, double GS = 0) : endsAt(endsAt), speed(speed), altitude(altitude), speedRestriction(speedRestriction), phase(usagePhase), fpm(FPM), distToArr(DTA), gs(GS) {}
template <class B> void store(B& buf) const;
template <class B> void parse(B& buf);
};
enum class LocationType
{
Absolute,
Hold,
Relative,
PerfBased,
Abstract
};
struct NavDataObj
{
protected:
int ID = -1;
public:
std::wstring identifier;
LatitudeLongitude latlon;
int Flag = 0;
Winds winds[4];
double tempAlt = ALT_INVALID;
double temp = TEMP_INVALID;
double altRestr = ALT_INVALID;
double altRestrLower = ALT_INVALID;
AltitudeRestrictionType altRestrictionType = AltitudeRestrictionType::Unspecified;
double speed_restr = SPD_INVALID;
bool isFlyover = false;
//ObjectUsagePhase usagePhase = ObjectUsagePhase::Unknown;
ObjectUsage usage = ObjectUsage::Leg;
double progress = 0.0;
double distToNext = DIST_INVALID;
double distToArrival = DIST_INVALID;
double bearingFromTo = 0;
double bearingToFrom = 0;
double fuelBurnToNext = 0;
bool efobSet = false;
double efob = -1;
double ete = -1;
double eto = -1;
double ato = -1;
//Values for use in internal calculations only
struct Calculation
{
double secToNextLeg = -1;
double progToNextLeg = 0.0;
double distToNextLeg = DIST_INVALID;
template <class B> void store(B& buf) const;
template <class B> void parse(B& buf);
} calc;
//
size_t currLatSegment = 0;
std::vector<LateralSegment> latSegments;
size_t currVertSegment = 0;
std::vector< VerticalSegment> vertSegments;
static std::shared_ptr<NavDataObj> Copy(std::shared_ptr<NavDataObj> obj);
double GetPredictedAltitude() const;
double GetPredictedSpeed() const;
ObjectUsagePhase GetUsagePhase() const;
int GetID() const;
void SetID(int id);
virtual bool IsConditional() const;
virtual LocationType GetLocationType() const;
virtual const NavDataObjType GetType() const = 0;
virtual LatitudeLongitude GetLatitudeLongitude() const;
virtual std::wstring GetIdentifier() const;
virtual ~NavDataObj();
template <class B> void store(B& buf) const;
template <class B> void parse(B& buf);
};
struct Runway : public NavDataObj {
double true_heading;
short length;
short width;
std::wstring surface;
short elevation;
virtual const NavDataObjType GetType() const;
Runway();
template <class B> void store(B& buf) const;
template <class B> void parse(B& buf);
};
enum class HoldType
{
Standard,
Manual,
Database,
DatabaseEdited
};
struct HoldParameters
{
std::wstring wptIdent;
HoldType type = HoldType::Standard;
bool holdDistManual = false;
double holdDist = -1;
bool holdTimeManual = true;
double holdTime = -1;
TurnDirection holdDir = TurnDirection::Right;
double holdInboundCourse = -1;
double holdLimitTime = -1;
double holdLimitFuel = -1;
bool holdExit = false;
double defaultCourse = -1;
double defaultTime = -1;
template <class B> void parse(B& buf);
template <class B> void store(B& buf) const;
};
struct Hold : public NavDataObj, HoldParameters {
virtual const NavDataObjType GetType() const override;
virtual bool IsConditional() const override;
virtual LocationType GetLocationType() const override;
double GetSpeedRestriction(double altitude) const;
void Update(HoldParameters params);
Hold();
template <class B> void store(B& buf) const;
template <class B> void parse(B& buf);
};
enum class NavaidType
{
VOR = 1,
VORTAC = 2,
TACAN = 3,
VORDME = 4,
NDB = 5,
NDBDME = 7,
ILSDME = 8,
DME = 9
};
struct Navaid : public NavDataObj {
NavaidType type;
std::wstring name;
std::wstring country;
int frequency;
std::wstring channel;
std::wstring usage;
int elevation;
double slaved_var;
virtual const NavDataObjType GetType() const;
Navaid();
template <class B> void parse(B& buf);
template <class B> void store(B& buf) const;
};
struct Waypoint : public NavDataObj {
bool collocated;
std::wstring name;
std::wstring country;
int navaidID;
virtual const NavDataObjType GetType() const;
Waypoint();
template <class B> void store(B& buf) const;
template <class B> void parse(B& buf);
};
struct AirwayLeg : public NavDataObj {
int airway_id;
std::wstring airway_ident;
std::wstring level;
std::wstring wpt1Ident;
int wpt1ID;
int wpt2ID;
bool is_start;
bool is_end;
virtual const NavDataObjType GetType() const;
AirwayLeg();
template <class B> void store(B& buf) const;
template <class B> void parse(B& buf);
};
struct Airway {
int ID;
std::wstring identifier;
AirwayStatus status;
std::vector<AirwayLeg> legs;
Airway();
template <class B> void store(B& buf) const;
template <class B> void parse(B& buf);
};
struct Discontinuity : public NavDataObj {
virtual bool IsConditional() const override;
virtual const NavDataObjType GetType() const override;
virtual std::wstring GetIdentifier() const override;
virtual LocationType GetLocationType() const override;
template <class B> void store(B& buf) const;
template <class B> void parse(B& buf);
};
struct LatitudeLongitudeWaypoint : public NavDataObj {
virtual LocationType GetLocationType() const override;
virtual const NavDataObjType GetType() const;
LatitudeLongitudeWaypoint();
template <class B> void store(B& buf) const;
template <class B> void parse(B& buf);
};
struct PilotDefinedWaypoint : public NavDataObj {
std::wstring pbd_place;
int pbd_brg;
int pbd_dist;
int elev;
int crs;
int length;
bool is_defined = false;
bool IsRunway() const;
virtual const NavDataObjType GetType() const;
PilotDefinedWaypoint();
template <class B> void store(B& buf) const;
template <class B> void parse(B& buf);
};
struct TerminalLeg : public NavDataObj {
int terminal_id;
std::shared_ptr<NavDataObj> via;
char type;
TrackCode track_code;
std::wstring transition;
Waypoint wpt;
Navaid nvd;
HoldParameters hold;
ObjectTurnDirection turn_dir;
double course;
double distance;
LatitudeLongitude refLatLon;
LatitudeLongitude destLatlon;
double bearToDest;
double distToDest;
double vnav;
int center_id;
LatitudeLongitude center_latlon;
virtual const NavDataObjType GetType() const override;
virtual LatitudeLongitude GetLatitudeLongitude() const override;
double speed_limit;
bool is_missed_app_point;
bool is_final_app_fix;
virtual bool IsConditional() const override;
virtual LocationType GetLocationType() const override;
TerminalLeg();
template <class B> void store(B& buf) const;
template <class B> void parse(B& buf);
};
struct ILS {
int ID;
std::wstring identifier;
LatitudeLongitude latlon;
int runway_id;
int frequency;
double gs_angle;
short category;
double loc_course;
int crossing_height;
int elevation;
bool has_dme;
ILS();
template <class B> void store(B& buf) const;
template <class B> void parse(B& buf);
};
struct TerminalProcedure {
int ID;
std::wstring identifier;
//int airport_id;
//std::wstring icao;
char proc;
//std::wstring full_name;
//std::wstring runway;
std::wstring GetFormattedName();
std::vector<TerminalLeg> legs;
bool is_ils;
int runway_id;
TerminalProcedure();
template <class B> void store(B& buf) const;
template <class B> void parse(B& buf);
};
struct Airport : public NavDataObj {
std::wstring name;
int primaryid;
short elevation;
int transition_altitude;
Airport();
std::vector<Runway> runways;
std::vector<TerminalProcedure> sids;
std::vector<TerminalProcedure> stars;
std::vector<TerminalProcedure> approaches;
Airport& operator=(const Airport& otherapt);
bool operator==(Airport& otherapt);
bool operator!=(Airport& otherapt);
virtual const NavDataObjType GetType() const;
template <class B> void store(B& buf) const;
template <class B> void parse(B& buf);
};
struct Transition
{
std::wstring identifier;
template <class B> void store(B& buf) const;
template <class B> void parse(B& buf);
};
class WorldData
{
public:
static std::vector<LatitudeLongitude> LatLonSpread(LatitudeLongitude source, int numOfSteps);
static int LatToX(double lat);
static int LonToY(double lon);
std::vector<Airport> airports[181][361];
std::vector<Navaid> navaids[181][361];
std::vector<Waypoint> waypoints[181][361];
std::vector<Airway> airways;
std::vector<AirwayLeg> airwayLegs;
std::vector<ILS> ilses;
};
struct NavigationData {
private:
void name_terminal_leg(TerminalLeg& tl);
int which_terminal_leg_is_duplicate(TerminalLeg& tl1, TerminalLeg& tl2);
std::string dataDir;
public:
bool is_usable;
std::wstring cycle_name;
std::wstring cycle_start;
std::wstring cycle_end;
bool is_valid();
bool lookup_airport_by_id(int id, Airport & apt);
bool lookup_airport_by_icao(std::wstring icao, Airport & apt);
bool lookup_waypoint_by_id(int wptid, Waypoint& wpt);
bool lookup_navaid_by_id(int navid, Navaid& nd);
bool lookup_airway_by_ident(std::wstring ident, Airway& aw);
bool lookup_ils(int runway_id, ILS& ils);
std::vector<ILS> lookup_ils_by_frequency(int frequency);
std::vector<ILS> lookup_ils_by_ident(std::wstring ident);
bool intersect_airways(int airwayid1, int airwayid2, AirwayLeg& leg);
bool lookup_airway_legs(Airway awy, std::wstring waypoint1ident, std::wstring waypoint2ident, std::vector<AirwayLeg>& legs);
std::vector<Navaid> lookup_navaids_by_ident(std::wstring ident);
std::vector<Navaid> lookup_navaids_by_frequency(int frequency);
std::vector<Waypoint> lookup_waypoints_by_ident(std::wstring ident);
std::vector<Runway> lookup_runways(int airport_id, int terminal_id = -1);
double get_runway_slope(int airport_id, int runway_id);
WorldData worldData;
std::vector<Transition> lookup_sid_transitions(int sid_id);
std::vector<TerminalProcedure> lookup_sids(int airport_id, int runway_id = -1);
std::vector<TerminalLeg> lookup_sid_legs(int sid_id, std::wstring rwy, std::wstring transition);
std::vector<Transition> lookup_star_transitions(int star_id);
std::vector<TerminalProcedure> lookup_stars(int airport_id, int runway_id = -1);
std::vector<TerminalLeg> lookup_star_legs(int star_id, std::wstring rwy, std::wstring transition);
std::vector<Transition> lookup_approach_transitions(int approach_id);
std::vector<TerminalProcedure> lookup_approaches(int airport_id, int runway_id = -1, bool strict_runway_enforcement = false);
std::vector<TerminalLeg> lookup_approach_legs(int approach_id, std::wstring transition);
NavigationData(std::wstring dataDirectory);
~NavigationData();
};