// simple.hxx -- a really simplistic class to manage airport ID,
-// lat, lon of the center of one of it's runways, and
+// lat, lon of the center of one of it's runways, and
// elevation in feet.
//
// Written by Curtis Olson, started April 1998.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
-// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// $Id$
#ifndef _FG_SIMPLE_HXX
#define _FG_SIMPLE_HXX
-
-#ifndef __cplusplus
-# error This library requires C++
-#endif
-
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-#include <simgear/math/point3d.hxx>
-#include <simgear/route/waypoint.hxx>
#include <simgear/compiler.h>
-#include <simgear/xml/easyxml.hxx>
-#include STL_STRING
-#include <map>
-#include <set>
+#include <string>
#include <vector>
-SG_USING_STD(string);
-SG_USING_STD(map);
-SG_USING_STD(set);
-SG_USING_STD(vector);
-
-typedef vector<string> stringVec;
-typedef vector<string>::iterator stringVecIterator;
-typedef vector<string>::const_iterator stringVecConstIterator;
-
-typedef vector<time_t> timeVec;
-typedef vector<time_t>::const_iterator timeVecConstIterator;
-
-
-/***************************************************************************/
-class ScheduleTime {
-private:
- timeVec start;
- timeVec end;
- stringVec scheduleNames;
- double tailWind;
- double crssWind;
-public:
- ScheduleTime() {};
- ScheduleTime(const ScheduleTime &other);
- ScheduleTime &operator= (const ScheduleTime &other);
- string getName(time_t dayStart);
-
- void clear();
- void addStartTime(time_t time) { start.push_back(time); };
- void addEndTime (time_t time) { end. push_back(time); };
- void addScheduleName(const string& sched) { scheduleNames.push_back(sched); };
- void setTailWind(double wnd) { tailWind = wnd; };
- void setCrossWind(double wnd) { tailWind = wnd; };
-
- double getTailWind() { return tailWind; };
- double getCrossWind() { return crssWind; };
-};
-
-//typedef vector<ScheduleTime> ScheduleTimes;
-/*****************************************************************************/
-
-class RunwayList
-{
-private:
- string type;
- stringVec preferredRunways;
-public:
- RunwayList() {};
- RunwayList(const RunwayList &other);
- RunwayList& operator= (const RunwayList &other);
+#include <Navaids/positioned.hxx>
- void set(const string&, const string&);
- void clear();
-
- string getType() { return type; };
- stringVec *getRwyList() { return &preferredRunways; };
- string getRwyList(int j) { return preferredRunways[j]; };
-};
-
-typedef vector<RunwayList> RunwayListVec;
-typedef vector<RunwayList>::iterator RunwayListVectorIterator;
-typedef vector<RunwayList>::const_iterator RunwayListVecConstIterator;
-
-
-/*****************************************************************************/
-
-class RunwayGroup
-{
-private:
- string name;
- RunwayListVec rwyList;
- int active;
- //stringVec runwayNames;
- int choice[2];
- int nrActive;
-public:
- RunwayGroup() {};
- RunwayGroup(const RunwayGroup &other);
- RunwayGroup &operator= (const RunwayGroup &other);
-
- void setName(string nm) { name = nm; };
- void add(RunwayList list) { rwyList.push_back(list);};
- void setActive(const string& aptId, double windSpeed, double windHeading, double maxTail, double maxCross);
-
- int getNrActiveRunways() { return nrActive;};
- void getActive(int i, string& name, string& type);
-
- string getName() { return name; };
- void clear() { rwyList.clear(); };
- //void add(string, string);
-};
-
-typedef vector<RunwayGroup> PreferenceList;
-typedef vector<RunwayGroup>::iterator PreferenceListIterator;
-typedef vector<RunwayGroup>::const_iterator PreferenceListConstIterator;
-/******************************************************************************/
-
-class FGRunwayPreference : public XMLVisitor {
-private:
- string value;
- string scheduleName;
+// forward decls
+class FGAirportDynamics;
+class FGRunway;
+class FGTaxiway;
+class FGPavement;
+class SGPropertyNode;
- ScheduleTime comTimes; // Commercial Traffic;
- ScheduleTime genTimes; // General Aviation;
- ScheduleTime milTimes; // Military Traffic;
- ScheduleTime currTimes; // Needed for parsing;
+typedef SGSharedPtr<FGRunway> FGRunwayPtr;
+typedef SGSharedPtr<FGTaxiway> FGTaxiwayPtr;
+typedef SGSharedPtr<FGPavement> FGPavementPtr;
- RunwayList rwyList;
- RunwayGroup rwyGroup;
- PreferenceList preferences;
+namespace flightgear {
+ class SID;
+ class STAR;
+ class Approach;
+ class Waypt;
+ class CommStation;
- time_t processTime(const string&);
- bool initialized;
-
-public:
- FGRunwayPreference();
- FGRunwayPreference(const FGRunwayPreference &other);
-
- FGRunwayPreference & operator= (const FGRunwayPreference &other);
- ScheduleTime *getSchedule(const char *trafficType);
- RunwayGroup *getGroup(const string& groupName);
- bool available() { return initialized; };
-
- // Some overloaded virtual XMLVisitor members
- virtual void startXML ();
- virtual void endXML ();
- virtual void startElement (const char * name, const XMLAttributes &atts);
- virtual void endElement (const char * name);
- virtual void data (const char * s, int len);
- virtual void pi (const char * target, const char * data);
- virtual void warning (const char * message, int line, int column);
- virtual void error (const char * message, int line, int column);
-};
-
-double processPosition(const string& pos);
-
-class FGParking {
-private:
- double latitude;
- double longitude;
- double heading;
- double radius;
- int index;
- string parkingName;
- string type;
- string airlineCodes;
-
- bool available;
-
-
-
-public:
- FGParking() { available = true;};
- //FGParking(FGParking &other);
- FGParking(double lat,
- double lon,
- double hdg,
- double rad,
- int idx,
- const string& name,
- const string& tpe,
- const string& codes);
- void setLatitude (const string& lat) { latitude = processPosition(lat); };
- void setLongitude(const string& lon) { longitude = processPosition(lon); };
- void setHeading (double hdg) { heading = hdg; };
- void setRadius (double rad) { radius = rad; };
- void setIndex (int idx) { index = idx; };
- void setName (const string& name) { parkingName = name; };
- void setType (const string& tpe) { type = tpe; };
- void setCodes (const string& codes){ airlineCodes= codes;};
-
- bool isAvailable () { return available;};
- void setAvailable(bool val) { available = val; };
-
- double getLatitude () { return latitude; };
- double getLongitude() { return longitude; };
- double getHeading () { return heading; };
- double getRadius () { return radius; };
- int getIndex () { return index; };
- string getType () { return type; };
- string getCodes () { return airlineCodes;};
- string getName () { return parkingName; };
-
- bool operator< (const FGParking &other) const {return radius < other.radius; };
-};
-
-typedef vector<FGParking> FGParkingVec;
-typedef vector<FGParking>::iterator FGParkingVecIterator;
-typedef vector<FGParking>::const_iterator FGParkingVecConstIterator;
-
-class FGTaxiSegment; // forward reference
-
-typedef vector<FGTaxiSegment> FGTaxiSegmentVector;
-typedef vector<FGTaxiSegment*> FGTaxiSegmentPointerVector;
-typedef vector<FGTaxiSegment>::iterator FGTaxiSegmentVectorIterator;
-typedef vector<FGTaxiSegment*>::iterator FGTaxiSegmentPointerVectorIterator;
-
-/**************************************************************************************
- * class FGTaxiNode
- *************************************************************************************/
-class FGTaxiNode
-{
-private:
- double lat;
- double lon;
- int index;
- FGTaxiSegmentPointerVector next; // a vector to all the segments leaving from this node
-
-public:
- FGTaxiNode();
- FGTaxiNode(double, double, int);
-
- void setIndex(int idx) { index = idx;};
- void setLatitude (double val) { lat = val;};
- void setLongitude(double val) { lon = val;};
- void setLatitude (const string& val) { lat = processPosition(val); };
- void setLongitude(const string& val) { lon = processPosition(val); };
- void addSegment(FGTaxiSegment *segment) { next.push_back(segment); };
+ typedef SGSharedPtr<Waypt> WayptRef;
+ typedef std::vector<WayptRef> WayptVec;
- double getLatitude() { return lat;};
- double getLongitude(){ return lon;};
+ typedef std::vector<CommStation*> CommStationList;
+}
- int getIndex() { return index; };
- FGTaxiNode *getAddress() { return this;};
- FGTaxiSegmentPointerVectorIterator getBeginRoute() { return next.begin(); };
- FGTaxiSegmentPointerVectorIterator getEndRoute() { return next.end(); };
-};
-typedef vector<FGTaxiNode> FGTaxiNodeVector;
-typedef vector<FGTaxiNode>::iterator FGTaxiNodeVectorIterator;
-
-/***************************************************************************************
- * class FGTaxiSegment
- **************************************************************************************/
-class FGTaxiSegment
-{
-private:
- int startNode;
- int endNode;
- double length;
- FGTaxiNode *start;
- FGTaxiNode *end;
- int index;
-
-public:
- FGTaxiSegment();
- FGTaxiSegment(FGTaxiNode *, FGTaxiNode *, int);
-
- void setIndex (int val) { index = val; };
- void setStartNodeRef (int val) { startNode = val; };
- void setEndNodeRef (int val) { endNode = val; };
-
- void setStart(FGTaxiNodeVector *nodes);
- void setEnd (FGTaxiNodeVector *nodes);
- void setTrackDistance();
-
- FGTaxiNode * getEnd() { return end;};
- double getLength() { return length; };
- int getIndex() { return index; };
-
-
-};
-
-
-typedef vector<int> intVec;
-typedef vector<int>::iterator intVecIterator;
-
-class FGTaxiRoute
-{
-private:
- intVec nodes;
- double distance;
- intVecIterator currNode;
-
-public:
- FGTaxiRoute() { distance = 0; currNode = nodes.begin(); };
- FGTaxiRoute(intVec nds, double dist) { nodes = nds; distance = dist; currNode = nodes.begin();};
- bool operator< (const FGTaxiRoute &other) const {return distance < other.distance; };
- bool empty () { return nodes.begin() == nodes.end(); };
- bool next(int *val);
-
- void first() { currNode = nodes.begin(); };
-};
-
-typedef vector<FGTaxiRoute> TaxiRouteVector;
-typedef vector<FGTaxiRoute>::iterator TaxiRouteVectorIterator;
-
-/**************************************************************************************
- * class FGGroundNetWork
- *************************************************************************************/
-class FGGroundNetwork
-{
-private:
- bool hasNetwork;
- FGTaxiNodeVector nodes;
- FGTaxiSegmentVector segments;
- //intVec route;
- intVec traceStack;
- TaxiRouteVector routes;
-
- bool foundRoute;
- double totalDistance, maxDistance;
-
-public:
- FGGroundNetwork();
-
- void addNode (const FGTaxiNode& node);
- void addNodes (FGParkingVec *parkings);
- void addSegment(const FGTaxiSegment& seg);
-
- void init();
- bool exists() { return hasNetwork; };
- int findNearestNode(double lat, double lon);
- FGTaxiNode *findNode(int idx);
- FGTaxiRoute findShortestRoute(int start, int end);
- void trace(FGTaxiNode *, int, int, double dist);
-
-};
/***************************************************************************************
*
**************************************************************************************/
-class FGAirport : public XMLVisitor{
-private:
- string _id;
- double _longitude; // degrees
- double _latitude; // degrees
- double _elevation; // ft
- string _code; // depricated and can be removed
- string _name;
- bool _has_metar;
- FGParkingVec parkings;
- FGRunwayPreference rwyPrefs;
- FGGroundNetwork groundNetwork;
-
- time_t lastUpdate;
- string prevTrafficType;
- stringVec landing;
- stringVec takeoff;
-
- // Experimental keep a running average of wind dir and speed to prevent
- // Erratic runway changes.
- // Note: I should add these to the copy constructor and assigment operator to be
- // constistent
- double avWindHeading [10];
- double avWindSpeed [10];
-
- string chooseRunwayFallback();
-
-public:
- FGAirport();
- FGAirport(const FGAirport &other);
- //operator= (FGAirport &other);
- FGAirport(const string& id, double lon, double lat, double elev, const string& name, bool has_metar);
-
- void init();
- void getActiveRunway(const string& trafficType, int action, string& runway);
- bool getAvailableParking(double *lat, double *lon, double *heading, int *gate, double rad, const string& fltype,
- const string& acType, const string& airline);
- void getParking (int id, double *lat, double* lon, double *heading);
- FGParking *getParking(int i); // { if (i < parkings.size()) return parkings[i]; else return 0;};
- void releaseParking(int id);
- string getParkingName(int i);
- string getId() const { return _id;};
- const string &getName() const { return _name;};
- //FGAirport *getAddress() { return this; };
- //const string &getName() const { return _name;};
- // Returns degrees
- double getLongitude() const { return _longitude;};
- // Returns degrees
- double getLatitude() const { return _latitude; };
- // Returns ft
- double getElevation() const { return _elevation;};
- bool getMetar() const { return _has_metar;};
- FGGroundNetwork* getGroundNetwork() { return &groundNetwork; };
-
-
- void setId(const string& id) { _id = id;};
- void setMetar(bool value) { _has_metar = value; };
-
- void setRwyUse(const FGRunwayPreference& ref);
-
- // Some overloaded virtual XMLVisitor members
- virtual void startXML ();
- virtual void endXML ();
- virtual void startElement (const char * name, const XMLAttributes &atts);
- virtual void endElement (const char * name);
- virtual void data (const char * s, int len);
- virtual void pi (const char * target, const char * data);
- virtual void warning (const char * message, int line, int column);
- virtual void error (const char * message, int line, int column);
-};
-
-typedef map < string, FGAirport* > airport_map;
-typedef airport_map::iterator airport_map_iterator;
-typedef airport_map::const_iterator const_airport_map_iterator;
-
-typedef vector < FGAirport * > airport_list;
-typedef airport_list::iterator airport_list_iterator;
-typedef airport_list::const_iterator const_airport_list_iterator;
-
-
-class FGAirportList {
-
-private:
-
- airport_map airports_by_id;
- airport_list airports_array;
- set < string > ai_dirs;
-
+class FGAirport : public FGPositioned
+{
public:
-
- // Constructor (new)
- FGAirportList();
-
- // Destructor
- ~FGAirportList();
-
- // add an entry to the list
- void add( const string& id, const double longitude, const double latitude,
- const double elevation, const string& name, const bool has_metar );
-
- // search for the specified id.
- // Returns NULL if unsucessfull.
- FGAirport* search( const string& id );
-
- // Search for the next airport in ASCII sequence to the supplied id.
- // eg. id = "KDC" or "KDCA" would both return "KDCA".
- // If exact = true then only exact matches are returned.
- // NOTE: Numbers come prior to A-Z in ASCII sequence so id = "LD" would return "LD57", not "LDDP"
- // Implementation assumes airport codes are unique.
- // Returns NULL if unsucessfull.
- const FGAirport* findFirstById( const string& id, bool exact = false );
-
- // search for the airport closest to the specified position
- // (currently a linear inefficient search so it's probably not
- // best to use this at runtime.) If with_metar is true, then only
- // return station id's marked as having metar data.
- // Returns NULL if fails (unlikely unless none have metar and with_metar spec'd!)
- FGAirport* search( double lon_deg, double lat_deg, bool with_metar );
-
+ FGAirport(const std::string& id, const SGGeod& location, const SGGeod& tower,
+ const std::string& name, bool has_metar, Type aType);
+ ~FGAirport();
+
+ const std::string& getId() const { return ident(); }
+ const std::string& getName() const { return _name; }
+ double getLongitude() const { return longitude(); }
+ // Returns degrees
+ double getLatitude() const { return latitude(); }
+ // Returns ft
+ double getElevation() const { return elevation(); }
+ bool getMetar() const { return _has_metar; }
+ bool isAirport() const;
+ bool isSeaport() const;
+ bool isHeliport() const;
+
+ virtual const std::string& name() const
+ { return _name; }
+
+ const SGGeod& getTowerLocation() const { return _tower_location; }
+
+ void setMetar(bool value) { _has_metar = value; }
+
+ FGRunway* getActiveRunwayForUsage() const;
+
+ FGAirportDynamics *getDynamics();
+
+ unsigned int numRunways() const;
+ FGRunway* getRunwayByIndex(unsigned int aIndex) const;
+
+ bool hasRunwayWithIdent(const std::string& aIdent) const;
+ FGRunway* getRunwayByIdent(const std::string& aIdent) const;
+ FGRunway* findBestRunwayForHeading(double aHeading) const;
+
/**
- * Return the number of airports in the list.
+ * return the most likely target runway based on a position.
+ * Specifically, return the runway for which the course from aPos
+ * to the runway end, mostly closely matches the runway heading.
+ * This is a good approximation of which runway the position is on or
+ * aiming towards.
*/
- int size() const;
-
+ FGRunway* findBestRunwayForPos(const SGGeod& aPos) const;
+
+ /**
+ * Useful predicate for FMS/GPS/NAV displays and similar - check if this
+ * aiport has a hard-surfaced runway of at least the specified length.
+ */
+ bool hasHardRunwayOfLengthFt(double aLengthFt) const;
+
+ unsigned int numTaxiways() const;
+ FGTaxiway* getTaxiwayByIndex(unsigned int aIndex) const;
+
+ unsigned int numPavements() const;
+ FGPavement* getPavementByIndex(unsigned int aIndex) const;
+
+ void setRunwaysAndTaxiways(std::vector<FGRunwayPtr>& rwys,
+ std::vector<FGTaxiwayPtr>& txwys,
+ std::vector<FGPavementPtr>& pvts);
+
+ class AirportFilter : public Filter
+ {
+ public:
+ virtual bool pass(FGPositioned* aPos) const {
+ return passAirport(static_cast<FGAirport*>(aPos));
+ }
+
+ virtual Type minType() const {
+ return AIRPORT;
+ }
+
+ virtual Type maxType() const {
+ return AIRPORT;
+ }
+
+ virtual bool passAirport(FGAirport* aApt) const {
+ return true;
+ }
+ };
+
+ /**
+ * Filter which passes heliports and seaports in addition to airports
+ */
+ class PortsFilter : public AirportFilter
+ {
+ public:
+ virtual Type maxType() const {
+ return SEAPORT;
+ }
+ };
+
+ class HardSurfaceFilter : public AirportFilter
+ {
+ public:
+ HardSurfaceFilter(double minLengthFt);
+
+ virtual bool passAirport(FGAirport* aApt) const;
+
+ private:
+ double mMinLengthFt;
+ };
+
+
+ void setProcedures(const std::vector<flightgear::SID*>& aSids,
+ const std::vector<flightgear::STAR*>& aStars,
+ const std::vector<flightgear::Approach*>& aApproaches);
+
+ void addSID(flightgear::SID* aSid);
+ void addSTAR(flightgear::STAR* aStar);
+ void addApproach(flightgear::Approach* aApp);
+
+ unsigned int numSIDs() const;
+ flightgear::SID* getSIDByIndex(unsigned int aIndex) const;
+ flightgear::SID* findSIDWithIdent(const std::string& aIdent) const;
+
+ unsigned int numSTARs() const;
+ flightgear::STAR* getSTARByIndex(unsigned int aIndex) const;
+ flightgear::STAR* findSTARWithIdent(const std::string& aIdent) const;
+
+ unsigned int numApproaches() const;
+ flightgear::Approach* getApproachByIndex(unsigned int aIndex) const;
+
+ static void installPropertyListener();
+
+ /**
+ * Syntactic wrapper around FGPositioned::findClosest - find the closest
+ * match for filter, and return it cast to FGAirport. The default filter
+ * passes airports, but not seaports or heliports
+ */
+ static FGAirport* findClosest(const SGGeod& aPos, double aCuttofNm, Filter* filter = NULL);
+
+ /**
+ * Helper to look up an FGAirport instance by unique ident. Throws an
+ * exception if the airport could not be found - so callers can assume
+ * the result is non-NULL.
+ */
+ static FGAirport* getByIdent(const std::string& aIdent);
+
+ /**
+ * Helper to look up an FGAirport instance by unique ident. Returns NULL
+ * if the airport could not be found.
+ */
+ static FGAirport* findByIdent(const std::string& aIdent);
+
+ /**
+ * Specialised helper to implement the AirportList dialog. Performs a
+ * case-insensitive search on airport names and ICAO codes, and returns
+ * matches in a format suitable for use by a puaList.
+ */
+ static char** searchNamesAndIdents(const std::string& aFilter);
+
+ bool buildApproach(flightgear::Waypt* aEnroute, flightgear::STAR* aSTAR,
+ FGRunway* aRwy, flightgear::WayptVec& aRoute);
+
/**
- * Return a specific airport, by position.
+ * Given a destiation point, select the best SID and transition waypt from
+ * this airport. Returns (NULL,NULL) is no SIDs are defined, otherwise the
+ * best SID/transition is that which is closest to the destination point.
*/
- const FGAirport *getAirport( unsigned int index ) const;
-
+ std::pair<flightgear::SID*, flightgear::WayptRef> selectSID(const SGGeod& aDest, FGRunway* aRwy);
+
/**
- * Return a pointer to the raw airport list
+ * Select a STAR and enroute transition waypt, given an origin (departure) position.
+ * returns (NULL, NULL) is no suitable STAR is exists
*/
- inline const airport_list* getAirportList() { return(&airports_array); }
-
+ std::pair<flightgear::STAR*, flightgear::WayptRef> selectSTAR(const SGGeod& aOrigin, FGRunway* aRwy);
+
+ virtual flightgear::PositionedBinding* createBinding(SGPropertyNode* nd) const;
+
+ void setCommStations(flightgear::CommStationList& comms);
+
+ flightgear::CommStationList commStationsOfType(FGPositioned::Type aTy) const;
+
+ const flightgear::CommStationList& commStations() const
+ { return mCommStations; }
+private:
+ typedef std::vector<FGRunwayPtr>::const_iterator Runway_iterator;
/**
- * Mark the specified airport record as not having metar
+ * Helper to locate a runway by ident
*/
- void no_metar( const string &id );
+ Runway_iterator getIteratorForRunwayIdent(const std::string& aIdent) const;
+ // disable these
+ FGAirport operator=(FGAirport &other);
+ FGAirport(const FGAirport&);
+
/**
- * Mark the specified airport record as (yes) having metar
+ * helper to read airport data from the scenery XML files.
*/
- void has_metar( const string &id );
-
+ void loadSceneryDefinitions() const;
+
+ /**
+ * Helpers to process property data loaded from an ICAO.threshold.xml file
+ */
+ void readThresholdData(SGPropertyNode* aRoot);
+ void processThreshold(SGPropertyNode* aThreshold);
+
+ /**
+ * Helper to parse property data loaded from an ICAO.twr.xml filke
+ */
+ void readTowerData(SGPropertyNode* aRoot);
+
+ SGGeod _tower_location;
+ std::string _name;
+ bool _has_metar;
+ FGAirportDynamics *_dynamics;
+
+ void loadRunways() const;
+ void loadTaxiways() const;
+ void loadProcedures() const;
+
+ mutable bool mRunwaysLoaded;
+ mutable bool mTaxiwaysLoaded;
+ mutable bool mProceduresLoaded;
+
+ std::vector<FGRunwayPtr> mRunways;
+ std::vector<FGTaxiwayPtr> mTaxiways;
+ std::vector<FGPavementPtr> mPavements;
+
+ std::vector<flightgear::SID*> mSIDs;
+ std::vector<flightgear::STAR*> mSTARs;
+ std::vector<flightgear::Approach*> mApproaches;
+
+ flightgear::CommStationList mCommStations;
};
+// find basic airport location info from airport database
+const FGAirport *fgFindAirportID( const std::string& id);
+
+// get airport elevation
+double fgGetAirportElev( const std::string& id );
#endif // _FG_SIMPLE_HXX