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.
8 // Written by James Turner, started 2009.
10 // Copyright (C) 2009 Curtis L. Olson
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.
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.
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.
35 #include <simgear/structure/SGReferenced.hxx>
36 #include <simgear/structure/SGSharedPtr.hxx>
37 #include <simgear/props/props.hxx>
44 #include <Airports/simple.hxx>
45 typedef SGSharedPtr<FGAirport> FGAirportRef;
58 typedef SGSharedPtr<Waypt> WayptRef;
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.
70 /// waypoint was created automatically (not manually entered/loaded)
71 /// for example waypoints from airway routing or a procedure
72 WPT_GENERATED = 1 << 7,
74 WPT_DEPARTURE = 1 << 8,
77 /// waypoint generated by VNAV / speed management profile,
78 /// for step climbs or top of descent
80 WPT_APPROACH = 1 << 11
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
94 bool isMachRestrict(RouteRestriction rr);
97 * Abstract base class for waypoints (and things that are treated similarly
98 * by navigation systems)
100 class Waypt : public SGReferenced
105 RouteBase* owner() const
109 * Return true course (in degrees) and distance (in metres) from the provided
110 * position to this waypoint
112 virtual std::pair<double, double> courseAndDistanceFrom(const SGGeod& aPos) const;
114 virtual SGGeod position() const = 0;
117 * The Positioned associated with this element, if one exists
119 virtual FGPositioned* source() const
122 virtual double altitudeFt() const
123 { return _altitudeFt; }
125 virtual double speed() const
128 // wrapper - asserts if restriction type is _MACH
129 double speedKts() const;
131 // wrapper - asserts if restriction type is not _MACH
132 double speedMach() const;
134 virtual RouteRestriction altitudeRestriction() const
135 { return _altRestrict; }
137 virtual RouteRestriction speedRestriction() const
138 { return _speedRestrict; }
140 void setAltitude(double aAlt, RouteRestriction aRestrict);
141 void setSpeed(double aSpeed, RouteRestriction aRestrict);
144 * Identifier assoicated with the waypoint. Human-readable, but
145 * possibly quite terse, and definitiely not unique.
147 virtual std::string ident() const;
150 * Test if the specified flag is set for this element
152 virtual bool flag(WayptFlag aFlag) const;
154 virtual unsigned int flags() const
157 void setFlag(WayptFlag aFlag, bool aV = true);
162 static WayptRef createFromProperties(RouteBase* aOwner, SGPropertyNode_ptr aProp);
164 void saveAsNode(SGPropertyNode* node) const;
167 * Test if this element and another are 'the same', i.e matching
168 * ident and lat/lon are approximately equal
170 bool matches(Waypt* aOther) const;
173 * Test if this element and a position 'the same'
174 * this can be defined by either position, ident or both
176 bool matches(const SGGeod& aPos) const;
178 virtual std::string type() const = 0;
181 * Magentic variation at/in the vicinity of the waypoint.
182 * For some waypoint types this will always return 0.
184 virtual double magvarDeg() const;
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.
191 virtual double headingRadialDeg() const;
193 friend class NavdataVisitor;
195 Waypt(RouteBase* aOwner);
198 * Persistence helper - read node properties from a file
200 virtual void initFromProperties(SGPropertyNode_ptr aProp);
203 * Persistence helper - save this element to a node
205 virtual void writeToProperties(SGPropertyNode_ptr aProp) const;
207 typedef Waypt* (FactoryFunction)(RouteBase* aOwner) ;
208 static void registerFactory(const std::string aNodeType, FactoryFunction* aFactory);
211 double _speed; // knots IAS or mach
212 RouteRestriction _altRestrict;
213 RouteRestriction _speedRestrict;
217 * Create an instance of a concrete subclass, or throw an exception
219 static Waypt* createInstance(RouteBase* aOwner, const std::string& aTypeName);
222 unsigned short _flags;
223 mutable double _magVarDeg;
226 typedef std::vector<WayptRef> WayptVec;
234 virtual std::string ident() const = 0;
236 static void loadAirportProcedures(const SGPath& aPath, FGAirport* aApt);
238 static void dumpRouteToKML(const WayptVec& aRoute, const std::string& aName);
240 static void dumpRouteToKMLLineString(const std::string& aIdent,
241 const WayptVec& aRoute, std::ostream& aStream);
246 class FlightPlan : public RouteBase
250 virtual ~FlightPlan();
252 virtual std::string ident() const;
253 void setIdent(const std::string& s);
255 FlightPlan* clone(const std::string& newIdent = std::string()) const;
258 * flight-plan leg encapsulation
263 FlightPlan* owner() const
266 Waypt* waypoint() const
269 // reutrn the next leg after this one
270 Leg* nextLeg() const;
272 unsigned int index() const;
274 int altitudeFt() const;
277 int speedKts() const;
278 double speedMach() const;
280 RouteRestriction altitudeRestriction() const;
281 RouteRestriction speedRestriction() const;
283 void setSpeed(RouteRestriction ty, double speed);
284 void setAltitude(RouteRestriction ty, int altFt);
286 double courseDeg() const;
287 double distanceNm() const;
288 double distanceAlongRoute() const;
290 friend class FlightPlan;
292 Leg(FlightPlan* owner, WayptRef wpt);
294 Leg* cloneFor(FlightPlan* owner) const;
297 RouteRestriction _speedRestrict, _altRestrict;
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;
313 virtual void departureChanged() { }
314 virtual void arrivalChanged() { }
315 virtual void waypointsChanged() { }
317 virtual void currentWaypointChanged() { }
323 void removeInner(Delegate* d);
325 void runDepartureChanged();
326 void runArrivalChanged();
327 void runWaypointsChanged();
328 void runCurrentWaypointChanged();
330 friend class FlightPlan;
335 Leg* insertWayptAtIndex(Waypt* aWpt, int aIndex);
336 void insertWayptsAtIndex(const WayptVec& wps, int aIndex);
338 void deleteIndex(int index);
340 int clearWayptsWithFlag(WayptFlag flag);
342 int currentIndex() const
343 { return _currentIndex; }
345 void setCurrentIndex(int index);
347 Leg* currentLeg() const;
348 Leg* nextLeg() const;
349 Leg* previousLeg() const;
352 { return _legs.size(); }
354 Leg* legAtIndex(int index) const;
355 int findLegIndex(const Leg* l) const;
357 int findWayptIndex(const SGGeod& aPos) const;
359 bool load(const SGPath& p);
360 bool save(const SGPath& p);
362 FGAirportRef departureAirport() const
363 { return _departure; }
365 FGAirportRef destinationAirport() const
366 { return _destination; }
368 FGRunway* departureRunway() const
369 { return _departureRunway; }
371 FGRunway* destinationRunway() const
372 { return _destinationRunway; }
374 Approach* approach() const
375 { return _approach; }
377 void setDeparture(FGAirport* apt);
378 void setDeparture(FGRunway* rwy);
383 Transition* sidTransition() const;
385 void setSID(SID* sid, const std::string& transition = std::string());
387 void setSID(Transition* sidWithTrans);
389 void setDestination(FGAirport* apt);
390 void setDestination(FGRunway* rwy);
393 * note setting an approach will implicitly update the destination
394 * airport and runway to match
396 void setApproach(Approach* app);
401 Transition* starTransition() const;
403 void setSTAR(STAR* star, const std::string& transition = std::string());
405 void setSTAR(Transition* starWithTrans);
407 double totalDistanceNm() const
408 { return _totalDistance; }
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
417 WayptRef waypointFromString(const std::string& target);
419 void setDelegate(Delegate* d);
420 void removeDelegate(Delegate* d);
423 bool loadPlainTextRoute(const SGPath& path);
425 void loadVersion1XMLRoute(SGPropertyNode_ptr routeData);
426 void loadVersion2XMLRoute(SGPropertyNode_ptr routeData);
427 void loadXMLRouteHeader(SGPropertyNode_ptr routeData);
428 WayptRef parseVersion1XMLWaypt(SGPropertyNode* aWP);
430 double magvarDegAt(const SGGeod& pos) const;
435 FGAirportRef _departure, _destination;
436 FGRunway* _departureRunway, *_destinationRunway;
440 std::string _sidTransition, _starTransition;
442 double _totalDistance;
443 void rebuildLegData();
445 typedef std::vector<Leg*> LegVec;
451 } // of namespace flightgear
453 #endif // of FG_ROUTE_HXX