]> git.mxchange.org Git - flightgear.git/blob - src/Navaids/route.hxx
Create a real FlightPlan (and Leg) class
[flightgear.git] / src / Navaids / route.hxx
1 /**
2  * route.hxx - defines basic route and route-element classes. Route elements
3  * are specialised into waypoints and related things. Routes are any class tha
4  * owns a collection (list, tree, graph) of route elements - such as airways,
5  * procedures or a flight plan.
6  */
7  
8 // Written by James Turner, started 2009.
9 //
10 // Copyright (C) 2009  Curtis L. Olson
11 //
12 // This program is free software; you can redistribute it and/or
13 // modify it under the terms of the GNU General Public License as
14 // published by the Free Software Foundation; either version 2 of the
15 // License, or (at your option) any later version.
16 //
17 // This program is distributed in the hope that it will be useful, but
18 // WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20 // General Public License for more details.
21 //
22 // You should have received a copy of the GNU General Public License
23 // along with this program; if not, write to the Free Software
24 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
25
26 #ifndef FG_ROUTE_HXX
27 #define FG_ROUTE_HXX
28
29 // std
30 #include <vector>
31 #include <map>
32 #include <iosfwd>
33
34 // Simgear
35 #include <simgear/structure/SGReferenced.hxx>
36 #include <simgear/structure/SGSharedPtr.hxx>
37 #include <simgear/props/props.hxx>
38
39 // forward decls
40 class FGPositioned;
41 class SGPath;
42 class FGRunway;
43
44 #include <Airports/simple.hxx>
45 typedef SGSharedPtr<FGAirport> FGAirportRef;
46
47 namespace flightgear
48 {
49
50 // forward decls
51 class RouteBase;
52 class Waypt;
53 class NavdataVisitor;
54 class SID;
55 class STAR;
56 class Transition;
57   
58 typedef SGSharedPtr<Waypt> WayptRef;
59
60 typedef enum {
61         WPT_MAP           = 1 << 0, ///< missed approach point
62         WPT_IAF           = 1 << 1, ///< initial approach fix
63         WPT_FAF           = 1 << 2, ///< final approach fix
64         WPT_OVERFLIGHT    = 1 << 3, ///< must overfly the point directly
65         WPT_TRANSITION    = 1 << 4, ///< transition to/from enroute structure
66         WPT_MISS          = 1 << 5, ///< segment is part of missed approach
67   /// waypoint position is dynamic, i.e moves based on other criteria,
68   /// such as altitude, inbound course, or so on.
69   WPT_DYNAMIC       = 1 << 6,
70   /// waypoint was created automatically (not manually entered/loaded)
71   /// for example waypoints from airway routing or a procedure  
72   WPT_GENERATED     = 1 << 7,
73   
74   WPT_DEPARTURE     = 1 << 8,
75   WPT_ARRIVAL       = 1 << 9,
76   
77   /// waypoint generated by VNAV / speed management profile,
78   /// for step climbs or top of descent
79   WPT_PSEUDO        = 1 << 10,
80   WPT_APPROACH      = 1 << 11
81 } WayptFlag;
82
83 typedef enum {
84         RESTRICT_NONE,
85         RESTRICT_AT,
86         RESTRICT_ABOVE,
87         RESTRICT_BELOW,
88   SPEED_RESTRICT_MACH,  ///< encode an 'AT' restriction in Mach, not IAS
89   RESTRICT_DELETE,      ///< ignore underlying restriction (on a leg)
90   RESTRICT_COMPUTED,    ///< data is computed, not a real restriction
91   SPEED_COMPUTED_MACH   ///< variant on above to encode a Mach value
92 } RouteRestriction;
93
94 bool isMachRestrict(RouteRestriction rr);
95   
96 /**
97  * Abstract base class for waypoints (and things that are treated similarly
98  * by navigation systems)
99  */
100 class Waypt : public SGReferenced
101 {
102 public:
103   virtual ~Waypt();
104   
105         RouteBase* owner() const 
106                 { return _owner; }
107   
108   /**
109    * Return true course (in degrees) and distance (in metres) from the provided
110    * position to this waypoint
111    */
112   virtual std::pair<double, double> courseAndDistanceFrom(const SGGeod& aPos) const;
113                         
114         virtual SGGeod position() const = 0;
115         
116         /**
117          * The Positioned associated with this element, if one exists
118          */
119         virtual FGPositioned* source() const
120                 { return NULL; }
121         
122         virtual double altitudeFt() const 
123                 { return _altitudeFt; }
124                 
125   virtual double speed() const
126     { return _speed; }
127   
128 // wrapper - asserts if restriction type is _MACH
129   double speedKts() const;
130   
131 // wrapper - asserts if restriction type is not _MACH
132   double speedMach() const;
133   
134         virtual RouteRestriction altitudeRestriction() const
135                 { return _altRestrict; }
136         
137         virtual RouteRestriction speedRestriction() const
138                 { return _speedRestrict; }
139         
140   void setAltitude(double aAlt, RouteRestriction aRestrict);
141   void setSpeed(double aSpeed, RouteRestriction aRestrict);
142   
143   /**
144    * Identifier assoicated with the waypoint. Human-readable, but
145    * possibly quite terse, and definitiely not unique.
146    */
147         virtual std::string ident() const;
148         
149         /**
150          * Test if the specified flag is set for this element
151          */
152         virtual bool flag(WayptFlag aFlag) const;
153         
154   void setFlag(WayptFlag aFlag, bool aV = true);
155   
156   /**
157    * Factory method
158    */
159   static WayptRef createFromProperties(RouteBase* aOwner, SGPropertyNode_ptr aProp);
160   
161   void saveAsNode(SGPropertyNode* node) const;
162   
163   /**
164    * Test if this element and another are 'the same', i.e matching
165    * ident and lat/lon are approximately equal
166    */
167   bool matches(Waypt* aOther) const;
168
169   /**
170    * Test if this element and a position 'the same'
171    * this can be defined by either position, ident or both
172    */
173   bool matches(const SGGeod& aPos) const;
174   
175   virtual std::string type() const = 0;
176   
177   /**
178    * Magentic variation at/in the vicinity of the waypoint.
179    * For some waypoint types this will always return 0.
180    */
181   virtual double magvarDeg() const;
182   
183   /**
184    * return the assoicated heading  or radial for this waypoint.
185    * The exact meaning varies by type - for a hold it's the inbound radial,
186    * for a DME intercept it's the heading to hold, and so on. 
187    */
188   virtual double headingRadialDeg() const;
189 protected:
190   friend class NavdataVisitor;
191   
192         Waypt(RouteBase* aOwner);
193   
194   /**
195    * Persistence helper - read node properties from a file
196    */
197   virtual void initFromProperties(SGPropertyNode_ptr aProp);
198   
199   /**
200    * Persistence helper - save this element to a node
201    */
202   virtual void writeToProperties(SGPropertyNode_ptr aProp) const;
203   
204   typedef Waypt* (FactoryFunction)(RouteBase* aOwner) ;
205   static void registerFactory(const std::string aNodeType, FactoryFunction* aFactory);
206   
207   double _altitudeFt;
208         double _speed; // knots IAS or mach
209         RouteRestriction _altRestrict;
210         RouteRestriction _speedRestrict;
211 private:
212
213   /**
214    * Create an instance of a concrete subclass, or throw an exception
215    */
216   static Waypt* createInstance(RouteBase* aOwner, const std::string& aTypeName);
217
218         RouteBase* _owner;
219         unsigned short _flags;
220   mutable double _magVarDeg; 
221 };
222
223 typedef std::vector<WayptRef> WayptVec;
224   
225 class RouteBase
226 {
227 public:
228   /**
229    *
230    */
231   virtual std::string ident() const = 0;
232   
233   static void loadAirportProcedures(const SGPath& aPath, FGAirport* aApt);
234   
235   static void dumpRouteToKML(const WayptVec& aRoute, const std::string& aName);
236   
237   static void dumpRouteToKMLLineString(const std::string& aIdent,
238     const WayptVec& aRoute, std::ostream& aStream);
239 private:
240
241 };
242   
243 class FlightPlan : public RouteBase
244 {
245 public:
246   FlightPlan();
247   virtual ~FlightPlan();
248   
249   virtual std::string ident() const;
250   void setIdent(const std::string& s);
251   
252   FlightPlan* clone(const std::string& newIdent = std::string()) const;
253   
254   /**
255    * flight-plan leg encapsulation
256    */
257   class Leg
258   {
259   public:
260     FlightPlan* owner() const
261     { return _parent; }
262     
263     Waypt* waypoint() const
264     { return _waypt; }
265     
266     // reutrn the next leg after this one
267     Leg* nextLeg() const;
268     
269     unsigned int index() const;
270     
271     int altitudeFt() const;             
272     int speed() const;
273     
274     int speedKts() const;
275     double speedMach() const;
276     
277     RouteRestriction altitudeRestriction() const;    
278     RouteRestriction speedRestriction() const;
279     
280     void setSpeed(RouteRestriction ty, double speed);
281     void setAltitude(RouteRestriction ty, int altFt);
282     
283     double courseDeg() const;
284     double distanceNm() const;
285     double distanceAlongRoute() const;
286   private:
287     friend class FlightPlan;
288     
289     Leg(FlightPlan* owner, WayptRef wpt);
290     
291     Leg* cloneFor(FlightPlan* owner) const;
292     
293     FlightPlan* _parent;
294     RouteRestriction _speedRestrict, _altRestrict;
295     int _speed;
296     int _altitudeFt;
297     WayptRef _waypt;
298     /// length of this leg following the flown path
299     mutable double _pathDistance;
300     mutable double _courseDeg;
301     /// total distance of this leg from departure point
302     mutable double _distanceAlongPath; 
303   };
304   
305   class Delegate
306   {
307   public:
308     virtual ~Delegate();
309     
310     virtual void departureChanged() { }
311     virtual void arrivalChanged() { }
312     virtual void waypointsChanged() { }
313     
314     virtual void currentWaypointChanged() { }
315   
316   protected:
317     Delegate();
318     
319   private:
320     void removeInner(Delegate* d);
321     
322     void runDepartureChanged();
323     void runArrivalChanged();
324     void runWaypointsChanged();
325     void runCurrentWaypointChanged();
326     
327     friend class FlightPlan;
328     
329     Delegate* _inner;
330   };
331   
332   Leg* insertWayptAtIndex(Waypt* aWpt, int aIndex);
333   void insertWayptsAtIndex(const WayptVec& wps, int aIndex);
334   
335   void deleteIndex(int index);
336   void clear();
337   int clearWayptsWithFlag(WayptFlag flag);
338   
339   int currentIndex() const
340   { return _currentIndex; }
341   
342   void setCurrentIndex(int index);
343   
344   Leg* currentLeg() const;
345   Leg* nextLeg() const;
346   Leg* previousLeg() const;
347   
348   int numLegs() const
349   { return _legs.size(); }
350   
351   Leg* legAtIndex(int index) const;
352   int findLegIndex(const Leg* l) const;
353   
354   int findWayptIndex(const SGGeod& aPos) const;
355   
356   bool load(const SGPath& p);
357   bool save(const SGPath& p);
358   
359   FGAirportRef departureAirport() const
360   { return _departure; }
361   
362   FGAirportRef destinationAirport() const
363   { return _destination; }
364   
365   FGRunway* departureRunway() const
366   { return _departureRunway; }
367   
368   FGRunway* destinationRunway() const
369   { return _destinationRunway; }
370   
371   Approach* approach() const
372   { return _approach; }
373   
374   void setDeparture(FGAirport* apt);
375   void setDeparture(FGRunway* rwy);
376   
377   SID* sid() const
378   { return _sid; }
379   
380   Transition* sidTransition() const;
381   
382   void setSID(SID* sid, const std::string& transition = std::string());
383   
384   void setSID(Transition* sidWithTrans);
385   
386   void setDestination(FGAirport* apt);
387   void setDestination(FGRunway* rwy);
388   
389   /**
390     * note setting an approach will implicitly update the destination
391     * airport and runway to match
392     */
393   void setApproach(Approach* app);
394   
395   STAR* star() const
396   { return _star; }
397   
398   Transition* starTransition() const;
399   
400   void setSTAR(STAR* star, const std::string& transition = std::string());
401   
402   void setSTAR(Transition* starWithTrans);
403   
404   double totalDistanceNm() const
405   { return _totalDistance; }
406   
407   /**
408    * Create a WayPoint from a string in the following format:
409    *  - simple identifier
410    *  - decimal-lon,decimal-lat
411    *  - airport-id/runway-id
412    *  - navaid/radial-deg/offset-nm
413    */
414   WayptRef waypointFromString(const std::string& target);
415   
416   void setDelegate(Delegate* d);
417   void removeDelegate(Delegate* d);
418 private:
419   
420   bool loadPlainTextRoute(const SGPath& path);
421   
422   void loadVersion1XMLRoute(SGPropertyNode_ptr routeData);
423   void loadVersion2XMLRoute(SGPropertyNode_ptr routeData);
424   void loadXMLRouteHeader(SGPropertyNode_ptr routeData);
425   WayptRef parseVersion1XMLWaypt(SGPropertyNode* aWP);
426   
427   double magvarDegAt(const SGGeod& pos) const;
428   
429   std::string _ident;
430   int _currentIndex;
431   
432   FGAirportRef _departure, _destination;
433   FGRunway* _departureRunway, *_destinationRunway;
434   SID* _sid;
435   STAR* _star;
436   Approach* _approach;
437   std::string _sidTransition, _starTransition;
438   
439   double _totalDistance;
440   void rebuildLegData();
441   
442   typedef std::vector<Leg*> LegVec;
443   LegVec _legs;
444   
445   Delegate* _delegate;
446 };
447   
448 } // of namespace flightgear
449
450 #endif // of FG_ROUTE_HXX