]> git.mxchange.org Git - flightgear.git/blob - src/Navaids/route.hxx
Expose procedure routing and fixes to Nasal.
[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   virtual unsigned int flags() const
155   { return _flags; }
156   
157   void setFlag(WayptFlag aFlag, bool aV = true);
158   
159   /**
160    * Factory method
161    */
162   static WayptRef createFromProperties(RouteBase* aOwner, SGPropertyNode_ptr aProp);
163   
164   void saveAsNode(SGPropertyNode* node) const;
165   
166   /**
167    * Test if this element and another are 'the same', i.e matching
168    * ident and lat/lon are approximately equal
169    */
170   bool matches(Waypt* aOther) const;
171
172   /**
173    * Test if this element and a position 'the same'
174    * this can be defined by either position, ident or both
175    */
176   bool matches(const SGGeod& aPos) const;
177   
178   virtual std::string type() const = 0;
179   
180   /**
181    * Magentic variation at/in the vicinity of the waypoint.
182    * For some waypoint types this will always return 0.
183    */
184   virtual double magvarDeg() const;
185   
186   /**
187    * return the assoicated heading  or radial for this waypoint.
188    * The exact meaning varies by type - for a hold it's the inbound radial,
189    * for a DME intercept it's the heading to hold, and so on. 
190    */
191   virtual double headingRadialDeg() const;
192 protected:
193   friend class NavdataVisitor;
194   
195         Waypt(RouteBase* aOwner);
196   
197   /**
198    * Persistence helper - read node properties from a file
199    */
200   virtual void initFromProperties(SGPropertyNode_ptr aProp);
201   
202   /**
203    * Persistence helper - save this element to a node
204    */
205   virtual void writeToProperties(SGPropertyNode_ptr aProp) const;
206   
207   typedef Waypt* (FactoryFunction)(RouteBase* aOwner) ;
208   static void registerFactory(const std::string aNodeType, FactoryFunction* aFactory);
209   
210   double _altitudeFt;
211         double _speed; // knots IAS or mach
212         RouteRestriction _altRestrict;
213         RouteRestriction _speedRestrict;
214 private:
215
216   /**
217    * Create an instance of a concrete subclass, or throw an exception
218    */
219   static Waypt* createInstance(RouteBase* aOwner, const std::string& aTypeName);
220
221         RouteBase* _owner;
222         unsigned short _flags;
223   mutable double _magVarDeg; 
224 };
225
226 typedef std::vector<WayptRef> WayptVec;
227   
228 class RouteBase
229 {
230 public:
231   /**
232    *
233    */
234   virtual std::string ident() const = 0;
235   
236   static void loadAirportProcedures(const SGPath& aPath, FGAirport* aApt);
237   
238   static void dumpRouteToKML(const WayptVec& aRoute, const std::string& aName);
239   
240   static void dumpRouteToKMLLineString(const std::string& aIdent,
241     const WayptVec& aRoute, std::ostream& aStream);
242 private:
243
244 };
245   
246 class FlightPlan : public RouteBase
247 {
248 public:
249   FlightPlan();
250   virtual ~FlightPlan();
251   
252   virtual std::string ident() const;
253   void setIdent(const std::string& s);
254   
255   FlightPlan* clone(const std::string& newIdent = std::string()) const;
256   
257   /**
258    * flight-plan leg encapsulation
259    */
260   class Leg
261   {
262   public:
263     FlightPlan* owner() const
264     { return _parent; }
265     
266     Waypt* waypoint() const
267     { return _waypt; }
268     
269     // reutrn the next leg after this one
270     Leg* nextLeg() const;
271     
272     unsigned int index() const;
273     
274     int altitudeFt() const;             
275     int speed() const;
276     
277     int speedKts() const;
278     double speedMach() const;
279     
280     RouteRestriction altitudeRestriction() const;    
281     RouteRestriction speedRestriction() const;
282     
283     void setSpeed(RouteRestriction ty, double speed);
284     void setAltitude(RouteRestriction ty, int altFt);
285     
286     double courseDeg() const;
287     double distanceNm() const;
288     double distanceAlongRoute() const;
289   private:
290     friend class FlightPlan;
291     
292     Leg(FlightPlan* owner, WayptRef wpt);
293     
294     Leg* cloneFor(FlightPlan* owner) const;
295     
296     FlightPlan* _parent;
297     RouteRestriction _speedRestrict, _altRestrict;
298     int _speed;
299     int _altitudeFt;
300     WayptRef _waypt;
301     /// length of this leg following the flown path
302     mutable double _pathDistance;
303     mutable double _courseDeg;
304     /// total distance of this leg from departure point
305     mutable double _distanceAlongPath; 
306   };
307   
308   class Delegate
309   {
310   public:
311     virtual ~Delegate();
312     
313     virtual void departureChanged() { }
314     virtual void arrivalChanged() { }
315     virtual void waypointsChanged() { }
316     
317     virtual void currentWaypointChanged() { }
318   
319   protected:
320     Delegate();
321     
322   private:
323     void removeInner(Delegate* d);
324     
325     void runDepartureChanged();
326     void runArrivalChanged();
327     void runWaypointsChanged();
328     void runCurrentWaypointChanged();
329     
330     friend class FlightPlan;
331     
332     Delegate* _inner;
333   };
334   
335   Leg* insertWayptAtIndex(Waypt* aWpt, int aIndex);
336   void insertWayptsAtIndex(const WayptVec& wps, int aIndex);
337   
338   void deleteIndex(int index);
339   void clear();
340   int clearWayptsWithFlag(WayptFlag flag);
341   
342   int currentIndex() const
343   { return _currentIndex; }
344   
345   void setCurrentIndex(int index);
346   
347   Leg* currentLeg() const;
348   Leg* nextLeg() const;
349   Leg* previousLeg() const;
350   
351   int numLegs() const
352   { return _legs.size(); }
353   
354   Leg* legAtIndex(int index) const;
355   int findLegIndex(const Leg* l) const;
356   
357   int findWayptIndex(const SGGeod& aPos) const;
358   
359   bool load(const SGPath& p);
360   bool save(const SGPath& p);
361   
362   FGAirportRef departureAirport() const
363   { return _departure; }
364   
365   FGAirportRef destinationAirport() const
366   { return _destination; }
367   
368   FGRunway* departureRunway() const
369   { return _departureRunway; }
370   
371   FGRunway* destinationRunway() const
372   { return _destinationRunway; }
373   
374   Approach* approach() const
375   { return _approach; }
376   
377   void setDeparture(FGAirport* apt);
378   void setDeparture(FGRunway* rwy);
379   
380   SID* sid() const
381   { return _sid; }
382   
383   Transition* sidTransition() const;
384   
385   void setSID(SID* sid, const std::string& transition = std::string());
386   
387   void setSID(Transition* sidWithTrans);
388   
389   void setDestination(FGAirport* apt);
390   void setDestination(FGRunway* rwy);
391   
392   /**
393     * note setting an approach will implicitly update the destination
394     * airport and runway to match
395     */
396   void setApproach(Approach* app);
397   
398   STAR* star() const
399   { return _star; }
400   
401   Transition* starTransition() const;
402   
403   void setSTAR(STAR* star, const std::string& transition = std::string());
404   
405   void setSTAR(Transition* starWithTrans);
406   
407   double totalDistanceNm() const
408   { return _totalDistance; }
409   
410   /**
411    * Create a WayPoint from a string in the following format:
412    *  - simple identifier
413    *  - decimal-lon,decimal-lat
414    *  - airport-id/runway-id
415    *  - navaid/radial-deg/offset-nm
416    */
417   WayptRef waypointFromString(const std::string& target);
418   
419   void setDelegate(Delegate* d);
420   void removeDelegate(Delegate* d);
421 private:
422   
423   bool loadPlainTextRoute(const SGPath& path);
424   
425   void loadVersion1XMLRoute(SGPropertyNode_ptr routeData);
426   void loadVersion2XMLRoute(SGPropertyNode_ptr routeData);
427   void loadXMLRouteHeader(SGPropertyNode_ptr routeData);
428   WayptRef parseVersion1XMLWaypt(SGPropertyNode* aWP);
429   
430   double magvarDegAt(const SGGeod& pos) const;
431   
432   std::string _ident;
433   int _currentIndex;
434   
435   FGAirportRef _departure, _destination;
436   FGRunway* _departureRunway, *_destinationRunway;
437   SID* _sid;
438   STAR* _star;
439   Approach* _approach;
440   std::string _sidTransition, _starTransition;
441   
442   double _totalDistance;
443   void rebuildLegData();
444   
445   typedef std::vector<Leg*> LegVec;
446   LegVec _legs;
447   
448   Delegate* _delegate;
449 };
450   
451 } // of namespace flightgear
452
453 #endif // of FG_ROUTE_HXX