// simple.hxx -- a really simplistic class to manage airport ID, // lat, lon of the center of one of it's runways, and // elevation in feet. // // Written by Curtis Olson, started April 1998. // Updated by Durk Talsma, started December 2004. // // Copyright (C) 1998 Curtis L. Olson - http://www.flightgear.org/~curt // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as // published by the Free Software Foundation; either version 2 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // General Public License for more details. // // 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. // // $Id$ #ifndef _FG_SIMPLE_HXX #define _FG_SIMPLE_HXX #ifndef __cplusplus # error This library requires C++ #endif #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include STL_STRING #include #include #include SG_USING_STD(string); SG_USING_STD(map); SG_USING_STD(set); SG_USING_STD(vector); typedef vector stringVec; typedef vector::iterator stringVecIterator; typedef vector::const_iterator stringVecConstIterator; typedef vector timeVec; typedef vector::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 ScheduleTimes; /*****************************************************************************/ class RunwayList { private: string type; stringVec preferredRunways; public: RunwayList() {}; RunwayList(const RunwayList &other); RunwayList& operator= (const RunwayList &other); 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 RunwayListVec; typedef vector::iterator RunwayListVectorIterator; typedef vector::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 PreferenceList; typedef vector::iterator PreferenceListIterator; typedef vector::const_iterator PreferenceListConstIterator; /******************************************************************************/ class FGRunwayPreference : public XMLVisitor { private: string value; string scheduleName; ScheduleTime comTimes; // Commercial Traffic; ScheduleTime genTimes; // General Aviation; ScheduleTime milTimes; // Military Traffic; ScheduleTime currTimes; // Needed for parsing; RunwayList rwyList; RunwayGroup rwyGroup; PreferenceList preferences; 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 FGParkingVec; typedef vector::iterator FGParkingVecIterator; typedef vector::const_iterator FGParkingVecConstIterator; class FGTaxiSegment; // forward reference typedef vector FGTaxiSegmentVector; typedef vector FGTaxiSegmentPointerVector; typedef vector::iterator FGTaxiSegmentVectorIterator; typedef vector::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); }; double getLatitude() { return lat;}; double getLongitude(){ return lon;}; int getIndex() { return index; }; FGTaxiNode *getAddress() { return this;}; FGTaxiSegmentPointerVectorIterator getBeginRoute() { return next.begin(); }; FGTaxiSegmentPointerVectorIterator getEndRoute() { return next.end(); }; }; typedef vector FGTaxiNodeVector; typedef vector::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 intVec; typedef vector::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 TaxiRouteVector; typedef vector::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; 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 ); /** * Return the number of airports in the list. */ int size() const; /** * Return a specific airport, by position. */ const FGAirport *getAirport( unsigned int index ) const; /** * Return a pointer to the raw airport list */ inline const airport_list* getAirportList() { return(&airports_array); } /** * Mark the specified airport record as not having metar */ void no_metar( const string &id ); /** * Mark the specified airport record as (yes) having metar */ void has_metar( const string &id ); }; #endif // _FG_SIMPLE_HXX