1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 //
3 // SPDX-FileCopyrightText: 2010 Dennis Nienhüser <nienhueser@kde.org>
4 //
5 
6 #ifndef MARBLE_ROUTINGINSTRUCTION_H
7 #define MARBLE_ROUTINGINSTRUCTION_H
8 
9 #include "RoutingWaypoint.h"
10 #include "RoutingPoint.h"
11 #include "marble_export.h"
12 
13 #include <QVector>
14 #include <QMetaType>
15 
16 class QTextStream;
17 
18 namespace Marble
19 {
20 
21 /**
22   * Stores data related to one instruction: Road name, angle to predecessor,
23   * associated waypoints etc. Can be streamed directly to a QTextStream.
24   */
25 class MARBLE_EXPORT RoutingInstruction
26 {
27 public:
28     enum TurnType {
29         Unknown = 0,
30         Continue = 13 /** Continue on the next street */,
31         Merge = 14,
32         Straight = 1,
33         SlightRight = 2,
34         Right = 3,
35         SharpRight = 4,
36         TurnAround = 5 /** Perform a u-turn */,
37         SharpLeft = 6,
38         Left = 7,
39         SlightLeft = 8,
40         RoundaboutFirstExit = 9 /** Enter the roundabout and leave at the first exit */,
41         RoundaboutSecondExit = 10 /** Enter the roundabout and leave at the second exit */,
42         RoundaboutThirdExit = 11 /** Enter the roundabout and leave at the third exit */,
43         RoundaboutExit = 12 /** At the point where the roundabout should be exited */,
44         ExitLeft = 15,
45         ExitRight = 16
46     };
47 
48     /** Constructor */
49     explicit RoutingInstruction( const RoutingWaypoint &item = RoutingWaypoint() );
50 
51     /**
52       * Append data of the given item, returns true if item's street
53       * name matches instructions street name
54       */
55     bool append( const RoutingWaypoint &item, int angle );
56 
57     /** Name of the road to turn into */
58     QString roadName() const;
59 
60     /** OSM type of the road to turn into */
61     QString roadType() const;
62 
63     /** Estimated number of seconds to the route destination */
64     int secondsLeft() const;
65 
66     /** Waypoints from the last instruction to this instruction */
67     QVector<RoutingWaypoint> points() const;
68 
69     /**
70       * Contains the intersection point and points near it on the previous and current road.
71       * Near is taken as that waypoint with the largest different to the intersection point
72       * that does not exceed 50 meter.
73       */
74     QVector<RoutingPoint> intersectionPoints() const;
75 
76     /** The angle between the two turn roads, in radians */
77     qreal angleToPredecssor() const;
78 
79     /** Previous turn road. Will be 0 for the first one (route start) */
80     RoutingInstruction* predecessor();
81 
82     /** Const overload for #predecessor */
83     const RoutingInstruction* predecessor() const;
84 
85     /** Change the predecessor */
86     void setPredecessor( RoutingInstruction* predecessor );
87 
88     /** Next turn road. Will be 0 for the last one (destination) */
89     RoutingInstruction* successor();
90 
91     /** Const overload for #successor */
92     const RoutingInstruction* successor() const;
93 
94     /** Change the successor */
95     void setSuccessor( RoutingInstruction* successor );
96 
97     /** The accumulated distance of all waypoints belonging to this instruction */
98     qreal distance() const;
99 
100     /** The distance from the route start */
101     qreal distanceFromStart() const;
102 
103     /** The distance to the route end. Includes the own distance */
104     qreal distanceToEnd() const;
105 
106     TurnType turnType() const;
107 
108     /** Formats the instruction (road name) for a human reader */
109     QString nextRoadInstruction() const;
110 
111     /** Formats the instruction (distance to next instruction) for a human reader */
112     QString nextDistanceInstruction() const;
113 
114     /** Formats the instruction (duration to destination) for a human reader */
115     QString totalDurationRemaining() const;
116 
117     /** Formats the instruction for a human reader */
118     QString instructionText() const;
119 
120     static QString generateRoadInstruction( TurnType turnType, const QString &roadName );
121 
122 protected:
123     int roundaboutExitNumber() const;
124 
125 private:
126     void calculateAngle();
127 
128     void calculateTurnType();
129 
130     QVector<RoutingWaypoint> m_points;
131 
132     QVector<RoutingPoint> m_intersectionPoints;
133 
134     QString m_roadName;
135 
136     QString m_roadType;
137 
138     int m_secondsLeft;
139 
140     qreal m_angleToPredecessor;
141 
142     TurnType m_turnType;
143 
144     int m_roundaboutExit;
145 
146     RoutingInstruction* m_predecessor;
147 
148     RoutingInstruction* m_successor;
149 };
150 
151 QTextStream& operator<<( QTextStream& stream, const RoutingInstruction &i );
152 
153 using RoutingInstructions = QVector<RoutingInstruction>;
154 
155 } // namespace Marble
156 
157 Q_DECLARE_METATYPE( Marble::RoutingInstruction::TurnType )
158 
159 #endif // MARBLE_ROUTINGINSTRUCTION_H
160