FlightGear next
runways.cxx
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: (C) 2000 Curtis L. Olson - http://www.flightgear.org/~curt
3 * SPDX_FileComment: a simple class to manage airport runway info
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7#include <config.h>
8
9#include <cassert>
10#include <simgear/compiler.h>
11
12#include <simgear/props/props.hxx>
13
14#include <string>
15
16#include "runways.hxx"
17
18#include <Airports/airport.hxx>
20#include <Navaids/navrecord.hxx>
21#include <Navaids/procedure.hxx>
22
23using std::string;
24
26 PositionedID aAirport, const string& aIdent,
27 const SGGeod& aGeod,
28 const double heading, const double length,
29 const double width,
30 const double displ_thresh,
31 const double stopway,
32 const int surface_code) : FGRunwayBase(aGuid, RUNWAY, aIdent, aGeod,
33 heading, length, width, surface_code, aAirport),
34 _reciprocal(0),
35 _displ_thresh(displ_thresh),
36 _stopway(stopway),
37 _ils(0)
38{
39}
40
41string FGRunway::reverseIdent(const string& aRunwayIdent)
42{
43 // Helipads don't have a seperate number per end
44 if (aRunwayIdent.size() && (aRunwayIdent[0] == 'H' || aRunwayIdent[0] == 'h' || aRunwayIdent[0] == 'x')) {
45 return aRunwayIdent;
46 }
47
48 std::string ident(aRunwayIdent);
49
50 int rn = std::stoi(ident.substr(0, 2));
51 rn += 18;
52 while (rn > 36) {
53 rn -= 36;
54 }
55
56 char buf[16];
57 snprintf(buf, sizeof(buf) - 1, "%02i", rn);
58
59 if (ident.size() == 3) {
60 char suffix = toupper(ident[2]);
61 if (suffix == 'L') {
62 buf[2] = 'R';
63 } else if (suffix == 'R') {
64 buf[2] = 'L';
65 } else {
66 // something else, just copy
67 buf[2] = suffix;
68 }
69
70 buf[3] = 0;
71 }
72
73 return buf;
74}
75
76double FGRunway::score(double aLengthWt, double aWidthWt, double aSurfaceWt, double aIlsWt) const
77{
78 int surface = 1;
79 if (_surface_code == 12 || _surface_code == 5) // dry lakebed & gravel
80 surface = 2;
81 else if (_surface_code == 1 || _surface_code == 2) // asphalt & concrete
82 surface = 3;
83
84 int ils = (_ils != 0);
85
86 return _length * aLengthWt + _width * aWidthWt + surface * aSurfaceWt + ils * aIlsWt + 1e-20;
87}
88
89SGGeod FGRunway::begin() const
90{
91 return pointOnCenterline(0.0);
92}
93
94SGGeod FGRunway::end() const
95{
96 return pointOnCenterline(lengthM());
97}
98
99SGGeod FGRunway::threshold() const
100{
101 return pointOnCenterline(_displ_thresh);
102}
103
104SGGeod FGRunway::pointOnCenterlineDisplaced(double aOffset) const
105{
106 return pointOnCenterline(_displ_thresh+aOffset);
107}
108
110{
111 assert(_reciprocal == 0);
112 _reciprocal = other;
113}
114
116{
117 return loadById<FGRunway>(_reciprocal);
118}
119
121{
122 if (_ils == 0) {
123 return NULL;
124 }
125
126 return loadById<FGNavRecord>(_ils);
127}
128
130{
133 if (gsId == 0) {
134 return NULL;
135 }
136
137 return loadById<FGNavRecord>(gsId);
138}
139
141{
142 FGAirport* apt = airport();
143 flightgear::SIDList result;
144 for (unsigned int i = 0; i < apt->numSIDs(); ++i) {
146 if (s->isForRunway(this)) {
147 result.push_back(s);
148 }
149 } // of SIDs at the airport iteration
150
151 return result;
152}
153
155{
156 FGAirport* apt = airport();
158 for (unsigned int i = 0; i < apt->numSTARs(); ++i) {
160 if (s->isForRunway(this)) {
161 result.push_back(s);
162 }
163 } // of STARs at the airport iteration
164
165 return result;
166}
167
170{
171 FGAirport* apt = airport();
173 for (unsigned int i = 0; i < apt->numApproaches(); ++i) {
175 if (s->runway() == this && (type == flightgear::PROCEDURE_INVALID || type == s->type())) {
176 result.push_back(s);
177 }
178 } // of approaches at the airport iteration
179
180 return result;
181}
182
183void FGRunway::updateThreshold(const SGGeod& newThreshold, double newHeading,
184 double newDisplacedThreshold,
185 double newStopway)
186{
187 modifyPosition(newThreshold);
188 _heading = newHeading;
189 _stopway = newStopway;
190 _displ_thresh = newDisplacedThreshold;
191}
192
194 PositionedID aAirport, const string& aIdent,
195 const SGGeod& aGeod,
196 const double heading, const double length,
197 const double width,
198 const int surface_code) : FGRunwayBase(aGuid, HELIPAD, aIdent, aGeod,
199 heading, length, width, surface_code, aAirport)
200{
201}
#define i(x)
flightgear::STAR * getSTARByIndex(unsigned int aIndex) const
Definition airport.cxx:914
unsigned int numApproaches() const
Definition airport.cxx:940
unsigned int numSIDs() const
Definition airport.cxx:873
flightgear::Approach * getApproachByIndex(unsigned int aIndex) const
Definition airport.cxx:947
unsigned int numSTARs() const
Definition airport.cxx:907
flightgear::SID * getSIDByIndex(unsigned int aIndex) const
Definition airport.cxx:880
FGHelipad(PositionedID aGuid, PositionedID aAirport, const std::string &rwy_no, const SGGeod &aGeod, const double heading, const double length, const double width, const int surface_code)
Definition runways.cxx:193
PositionedID guid() const
void modifyPosition(const SGGeod &newPos)
static SGSharedPtr< T > loadById(PositionedID id)
Type type() const
const std::string & ident() const
SGGeod pointOnCenterline(double aOffset) const
Retrieve a position on the extended centerline.
int surface() const
Retrieve runway surface code, as define in Robin Peel's data.
FGRunwayBase(PositionedID aGuid, Type aTy, const std::string &aIdent, const SGGeod &aGeod, const double heading, const double length, const double width, const int surface_code, const PositionedID airportId)
int _surface_code
surface, as defined by: http://www.x-plane.org/home/robinp/Apt810.htm#RwySfcCodes
double lengthM() const
double _heading
FGAirportRef airport() const
FGNavRecord * glideslope() const
retrieve the associated glideslope transmitter, if one is defined.
Definition runways.cxx:129
static std::string reverseIdent(const std::string &aRunayIdent)
given a runway identifier (06, 18L, 31R) compute the identifier for the reciprocal heading runway (24...
Definition runways.cxx:41
SGGeod pointOnCenterlineDisplaced(double aOffset) const
Retrieve a position on the extended centerline.
Definition runways.cxx:104
flightgear::STARList getSTARs() const
Get STARs associared with this runway.
Definition runways.cxx:154
SGGeod end() const
Get the 'far' end - this is equivalent to calling pointOnCenterline(lengthFt());.
Definition runways.cxx:94
SGGeod threshold() const
Get the (possibly displaced) threshold point.
Definition runways.cxx:99
void setReciprocalRunway(PositionedID other)
Definition runways.cxx:109
FGNavRecord * ILS() const
Definition runways.cxx:120
double score(double aLengthWt, double aWidthWt, double aSurfaceWt, double aIlsWt) const
score this runway according to the specified weights.
Definition runways.cxx:76
void updateThreshold(const SGGeod &newThreshold, double newHeading, double newDisplacedThreshold, double newStopway)
Definition runways.cxx:183
FGRunway * reciprocalRunway() const
Definition runways.cxx:115
flightgear::SIDList getSIDs() const
Get SIDs (DPs) associated with this runway.
Definition runways.cxx:140
SGGeod begin() const
Get the runway beginning point - this is syntatic sugar, equivalent to calling pointOnCenterline(0....
Definition runways.cxx:89
flightgear::ApproachList getApproaches(flightgear::ProcedureType type=flightgear::PROCEDURE_INVALID) const
Definition runways.cxx:169
FGRunway(PositionedID aGuid, PositionedID aAirport, const std::string &rwy_no, const SGGeod &aGeod, const double heading, const double length, const double width, const double displ_thresh, const double stopway, const int surface_code)
Definition runways.cxx:25
Describe an approach procedure, including the missed approach segment.
FGRunwayRef runway()
virtual ProcedureType type() const
virtual bool isForRunway(const FGRunway *aWay) const
Predicate, test if this procedure applies to the requested runway.
PositionedID findNavaidForRunway(PositionedID runway, FGPositioned::Type ty)
Given a runway and type, find the corresponding navaid (ILS / GS / OM)
static NavDataCache * instance()
std::vector< Approach * > ApproachList
std::vector< STAR * > STARList
std::vector< flightgear::SID * > SIDList
@ PROCEDURE_INVALID
Definition procedure.hxx:37
int64_t PositionedID