1 // airport.hxx -- a really simplistic class to manage airport ID, 2 // lat, lon of the center of one of it's runways, and 3 // elevation in feet. 4 // 5 // Written by Curtis Olson, started April 1998. 6 // Updated by Durk Talsma, started December 2004. 7 // 8 // Copyright (C) 1998 Curtis L. Olson - http://www.flightgear.org/~curt 9 // 10 // This program is free software; you can redistribute it and/or 11 // modify it under the terms of the GNU General Public License as 12 // published by the Free Software Foundation; either version 2 of the 13 // License, or (at your option) any later version. 14 // 15 // This program is distributed in the hope that it will be useful, but 16 // WITHOUT ANY WARRANTY; without even the implied warranty of 17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 // General Public License for more details. 19 // 20 // You should have received a copy of the GNU General Public License 21 // along with this program; if not, write to the Free Software 22 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 23 // 24 // $Id$ 25 26 27 #ifndef _FG_SIMPLE_HXX 28 #define _FG_SIMPLE_HXX 29 30 #include <simgear/compiler.h> 31 32 #include <string> 33 #include <vector> 34 #include <map> 35 #include <memory> 36 37 #include <Navaids/positioned.hxx> 38 #include <Navaids/procedure.hxx> 39 40 #include "airports_fwd.hxx" 41 #include "runways.hxx" 42 43 class FGGroundNetwork; 44 45 /*************************************************************************************** 46 * 47 **************************************************************************************/ 48 class FGAirport : public FGPositioned 49 { 50 public: 51 FGAirport(PositionedID aGuid, const std::string& id, const SGGeod& location, 52 const std::string& name, bool has_metar, Type aType); 53 ~FGAirport(); 54 isType(FGPositioned::Type ty)55 static bool isType(FGPositioned::Type ty) 56 { return (ty >= FGPositioned::AIRPORT) && (ty <= FGPositioned::SEAPORT); } 57 getId() const58 const std::string& getId() const { return ident(); } getName() const59 const std::string& getName() const { return _name; } toString() const60 std::string toString() const { return "an airport " + ident(); } 61 getLongitude() const62 double getLongitude() const { return longitude(); } 63 // Returns degrees getLatitude() const64 double getLatitude() const { return latitude(); } 65 // Returns ft getElevation() const66 double getElevation() const { return elevation(); } getMetar() const67 bool getMetar() const { return _has_metar; } 68 bool isAirport() const; 69 bool isSeaport() const; 70 bool isHeliport() const; 71 72 /// is the airport closed (disused)? 73 /// note at rpesent we look for an [x] in the name, ideally the database 74 /// would explicitly include this isClosed() const75 bool isClosed() const 76 { 77 return mIsClosed; 78 } 79 name() const80 virtual const std::string& name() const 81 { return _name; } 82 83 /** 84 * reload the ILS data from XML if required. 85 */ 86 void validateILSData(); 87 88 bool hasTower() const; 89 90 SGGeod getTowerLocation() const; 91 setMetar(bool value)92 void setMetar(bool value) { _has_metar = value; } 93 94 FGRunwayRef getActiveRunwayForUsage() const; 95 96 FGAirportDynamicsRef getDynamics() const; 97 98 FGGroundNetwork* groundNetwork() const; 99 100 unsigned int numRunways() const; 101 unsigned int numHelipads() const; 102 FGRunwayRef getRunwayByIndex(unsigned int aIndex) const; 103 FGHelipadRef getHelipadByIndex(unsigned int aIndex) const; 104 FGRunwayMap getRunwayMap() const; 105 FGHelipadMap getHelipadMap() const; 106 107 bool hasRunwayWithIdent(const std::string& aIdent) const; 108 bool hasHelipadWithIdent(const std::string& aIdent) const; 109 FGRunwayRef getRunwayByIdent(const std::string& aIdent) const; 110 FGHelipadRef getHelipadByIdent(const std::string& aIdent) const; 111 112 struct FindBestRunwayForHeadingParams { FindBestRunwayForHeadingParamsFGAirport::FindBestRunwayForHeadingParams113 FindBestRunwayForHeadingParams() { 114 lengthWeight = 0.01; 115 widthWeight = 0.01; 116 surfaceWeight = 10; 117 deviationWeight = 1; 118 ilsWeight = 0; 119 } 120 double lengthWeight; 121 double widthWeight; 122 double surfaceWeight; 123 double deviationWeight; 124 double ilsWeight; 125 }; 126 FGRunwayRef findBestRunwayForHeading(double aHeading, struct FindBestRunwayForHeadingParams * parms = NULL ) const; 127 128 /** 129 * return the most likely target runway based on a position. 130 * Specifically, return the runway for which the course from aPos 131 * to the runway end, mostly closely matches the runway heading. 132 * This is a good approximation of which runway the position is on or 133 * aiming towards. 134 */ 135 FGRunwayRef findBestRunwayForPos(const SGGeod& aPos) const; 136 137 /** 138 * Retrieve all runways at the airport, but excluding the reciprocal 139 * runways. For example at KSFO this might return 1L, 1R, 28L and 28R, 140 * but would not then include 19L/R or 10L/R. 141 * 142 * Exactly which runways you get, is undefined (i.e, dont assumes it's 143 * runways with heading < 180 degrees) - it depends on order in apt.dat. 144 * 145 * This is useful for code that wants to process each piece of tarmac at 146 * an airport *once*, not *twice* - eg mapping and nav-display code. 147 */ 148 FGRunwayList getRunwaysWithoutReciprocals() const; 149 150 /** 151 * Retrieve all runways at the airport 152 */ 153 FGRunwayList getRunways() const; 154 155 /** 156 * Useful predicate for FMS/GPS/NAV displays and similar - check if this 157 * aiport has a hard-surfaced runway of at least the specified length. 158 */ 159 bool hasHardRunwayOfLengthFt(double aLengthFt) const; 160 161 FGRunwayRef longestRunway() const; 162 163 unsigned int numTaxiways() const; 164 FGTaxiwayRef getTaxiwayByIndex(unsigned int aIndex) const; 165 FGTaxiwayList getTaxiways() const; 166 167 unsigned int numPavements() const; 168 FGPavementRef getPavementByIndex(unsigned int aIndex) const; 169 FGPavementList getPavements() const; 170 171 class AirportFilter : public Filter 172 { 173 public: pass(FGPositioned * aPos) const174 virtual bool pass(FGPositioned* aPos) const { 175 return passAirport(static_cast<FGAirport*>(aPos)); 176 } 177 minType() const178 virtual Type minType() const { 179 return AIRPORT; 180 } 181 maxType() const182 virtual Type maxType() const { 183 return AIRPORT; 184 } 185 passAirport(FGAirport * aApt) const186 virtual bool passAirport(FGAirport* aApt) const { 187 return true; 188 } 189 }; 190 191 /** 192 * Filter which passes heliports and seaports in addition to airports 193 */ 194 class PortsFilter : public AirportFilter 195 { 196 public: maxType() const197 virtual Type maxType() const { 198 return SEAPORT; 199 } 200 }; 201 202 class HardSurfaceFilter : public AirportFilter 203 { 204 public: 205 HardSurfaceFilter(double minLengthFt = -1); 206 207 virtual bool passAirport(FGAirport* aApt) const; 208 209 private: 210 double mMinLengthFt; 211 }; 212 213 /** 214 * Filter which passes specified port type and in case of airport checks 215 * if a runway larger the /sim/navdb/min-runway-lenght-ft exists. 216 */ 217 class TypeRunwayFilter: 218 public AirportFilter 219 { 220 public: 221 TypeRunwayFilter(); 222 223 /** 224 * Construct from string containing type (airport, seaport or heliport) 225 */ 226 bool fromTypeString(const std::string& type); 227 minType() const228 virtual FGPositioned::Type minType() const { return _type; } maxType() const229 virtual FGPositioned::Type maxType() const { return _type; } 230 virtual bool pass(FGPositioned* pos) const; 231 232 protected: 233 FGPositioned::Type _type; 234 double _min_runway_length_ft; 235 }; 236 237 238 void setProcedures(const std::vector<flightgear::SID*>& aSids, 239 const std::vector<flightgear::STAR*>& aStars, 240 const std::vector<flightgear::Approach*>& aApproaches); 241 242 void addSID(flightgear::SID* aSid); 243 void addSTAR(flightgear::STAR* aStar); 244 void addApproach(flightgear::Approach* aApp); 245 246 unsigned int numSIDs() const; 247 flightgear::SID* getSIDByIndex(unsigned int aIndex) const; 248 flightgear::SID* findSIDWithIdent(const std::string& aIdent) const; 249 flightgear::SIDList getSIDs() const; 250 251 flightgear::Transition* selectSIDByEnrouteTransition(FGPositioned* enroute) const; 252 flightgear::Transition* selectSIDByTransition(const FGRunway* runway, const std::string& aIdent) const; 253 254 unsigned int numSTARs() const; 255 flightgear::STAR* getSTARByIndex(unsigned int aIndex) const; 256 flightgear::STAR* findSTARWithIdent(const std::string& aIdent) const; 257 flightgear::STARList getSTARs() const; 258 259 flightgear::Transition* selectSTARByEnrouteTransition(FGPositioned* enroute) const; 260 flightgear::Transition* selectSTARByTransition(const FGRunway* runway, const std::string& aIdent) const; 261 262 unsigned int numApproaches() const; 263 flightgear::Approach* getApproachByIndex(unsigned int aIndex) const; 264 flightgear::Approach* findApproachWithIdent(const std::string& aIdent) const; 265 flightgear::ApproachList getApproaches 266 ( 267 flightgear::ProcedureType type = flightgear::PROCEDURE_INVALID 268 ) const; 269 270 /** 271 * Syntactic wrapper around FGPositioned::findClosest - find the closest 272 * match for filter, and return it cast to FGAirport. The default filter 273 * passes airports, but not seaports or heliports 274 */ 275 static FGAirportRef findClosest(const SGGeod& aPos, double aCuttofNm, Filter* filter = NULL); 276 277 /** 278 * Helper to look up an FGAirport instance by unique ident. Throws an 279 * exception if the airport could not be found - so callers can assume 280 * the result is non-NULL. 281 */ 282 static FGAirportRef getByIdent(const std::string& aIdent); 283 284 /** 285 * Helper to look up an FGAirport instance by unique ident. Returns NULL 286 * if the airport could not be found. 287 */ 288 static FGAirportRef findByIdent(const std::string& aIdent); 289 290 /** 291 * Specialised helper to implement the AirportList dialog. Performs a 292 * case-insensitive search on airport names and ICAO codes, and returns 293 * matches in a format suitable for use by a puaList. 294 */ 295 static char** searchNamesAndIdents(const std::string& aFilter); 296 297 298 /** 299 * Sort an FGPositionedList of airports by size (number of runways + length) 300 * this is meant to prioritise more important airports. 301 */ 302 static void sortBySize(FGPositionedList&); 303 304 flightgear::CommStationList commStationsOfType(FGPositioned::Type aTy) const; 305 306 flightgear::CommStationList commStations() const; 307 308 static void clearAirportsCache(); 309 310 311 #if defined(BUILDING_TESTSUITE) 312 // helper to allow testing without needing a full Airports heirarchy 313 void testSuiteInjectGroundnetXML(const SGPath& path); 314 #endif 315 private: 316 static flightgear::AirportCache airportCache; 317 318 // disable these 319 FGAirport operator=(FGAirport &other); 320 FGAirport(const FGAirport&); 321 322 /** 323 * helper to read airport data from the scenery XML files. 324 */ 325 void loadSceneryDefinitions() const; 326 327 /** 328 * Helpers to process property data loaded from an ICAO.threshold.xml file 329 */ 330 void readThresholdData(SGPropertyNode* aRoot); 331 void processThreshold(SGPropertyNode* aThreshold); 332 333 void readILSData(SGPropertyNode* aRoot); 334 335 void validateTowerData() const; 336 337 /** 338 * Helper to parse property data loaded from an ICAO.twr.xml file 339 */ 340 void readTowerData(SGPropertyNode* aRoot); 341 342 PositionedIDVec itemsOfType(FGPositioned::Type ty) const; 343 344 std::string _name; 345 bool _has_metar; 346 347 void loadRunways() const; 348 void loadHelipads() const; 349 void loadTaxiways() const; 350 void loadProcedures() const; 351 352 mutable bool mTowerDataLoaded; 353 mutable bool mHasTower; 354 mutable SGGeod mTowerPosition; 355 356 mutable bool mRunwaysLoaded; 357 mutable bool mHelipadsLoaded; 358 mutable bool mTaxiwaysLoaded; 359 mutable bool mProceduresLoaded; 360 bool mIsClosed; 361 mutable bool mThresholdDataLoaded; 362 bool mILSDataLoaded; 363 364 mutable std::vector<FGRunwayRef> mRunways; 365 366 mutable PositionedIDVec mHelipads; 367 mutable PositionedIDVec mTaxiways; 368 PositionedIDVec mPavements; 369 370 typedef SGSharedPtr<flightgear::SID> SIDRef; 371 typedef SGSharedPtr<flightgear::STAR> STARRef; 372 typedef SGSharedPtr<flightgear::Approach> ApproachRef; 373 374 std::vector<SIDRef> mSIDs; 375 std::vector<STARRef> mSTARs; 376 std::vector<ApproachRef> mApproaches; 377 378 mutable std::unique_ptr<FGGroundNetwork> _groundNetwork; 379 }; 380 381 // find basic airport location info from airport database 382 const FGAirport *fgFindAirportID( const std::string& id); 383 384 // get airport elevation 385 double fgGetAirportElev( const std::string& id ); 386 387 #endif // _FG_SIMPLE_HXX 388 389 390