Implemented street names/numbers parses and unit tests for it
[situare] / src / routing / routesegment.cpp
1 /*
2     Situare - A location system for Facebook
3     Copyright (C) 2010  Ixonos Plc. Authors:
4
5         Sami Rämö - sami.ramo@ixonos.com
6
7     Situare is free software; you can redistribute it and/or
8     modify it under the terms of the GNU General Public License
9     version 2 as published by the Free Software Foundation.
10
11     Situare is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with Situare; if not, write to the Free Software
18     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
19     USA.
20 */
21
22 #include <QDebug>
23 #include <QRegExp>
24
25 #include "routingcommon.h"
26
27 #include "routesegment.h"
28
29 RouteSegment::RouteSegment()
30     : m_timeSeconds(ROUTING_VALUE_UNDEFINED),
31       m_positionIndex(ROUTING_VALUE_UNDEFINED),
32       m_azimuth(ROUTING_VALUE_UNDEFINED),
33       m_length(ROUTING_VALUE_UNDEFINED),
34       m_turnAngle(ROUTING_VALUE_UNDEFINED)
35 {
36     qDebug() << __PRETTY_FUNCTION__;
37 }
38
39 qreal RouteSegment::azimuth() const
40 {
41     qDebug() << __PRETTY_FUNCTION__;
42
43     return m_azimuth;
44 }
45
46 QString RouteSegment::earthDirection() const
47 {
48     qDebug() << __PRETTY_FUNCTION__;
49
50     return m_earthDirection;
51 }
52
53 QString RouteSegment::instruction() const
54 {
55     qDebug() << __PRETTY_FUNCTION__;
56
57     return m_instruction;
58 }
59
60 qreal RouteSegment::length() const
61 {
62     qDebug() << __PRETTY_FUNCTION__;
63
64     return m_length;
65 }
66
67 QString RouteSegment::lengthCaption() const
68 {
69     qDebug() << __PRETTY_FUNCTION__;
70
71     return m_lengthCaption;
72 }
73
74 int RouteSegment::positionIndex() const
75 {
76     qDebug() << __PRETTY_FUNCTION__;
77
78     return m_positionIndex;
79 }
80
81 void RouteSegment::setAzimuth(qreal azimuth)
82 {
83     qDebug() << __PRETTY_FUNCTION__;
84
85     m_azimuth = azimuth;
86 }
87
88 void RouteSegment::setEarthDirection(QString direction)
89 {
90     qDebug() << __PRETTY_FUNCTION__;
91
92     m_earthDirection = direction;
93 }
94
95 void RouteSegment::setInstruction(QString instruction)
96 {
97     qDebug() << __PRETTY_FUNCTION__;
98
99     m_instruction = instruction;
100 }
101
102 void RouteSegment::setLength(qreal meters)
103 {
104     qDebug() << __PRETTY_FUNCTION__;
105
106     m_length = meters;
107 }
108
109 void RouteSegment::setLengthCaption(QString length)
110 {
111     qDebug() << __PRETTY_FUNCTION__;
112
113     m_lengthCaption = length;
114 }
115
116 void RouteSegment::setPositionIndex(int index)
117 {
118     qDebug() << __PRETTY_FUNCTION__;
119
120     m_positionIndex = index;
121 }
122
123 void RouteSegment::setTime(int seconds)
124 {
125     qDebug() << __PRETTY_FUNCTION__;
126
127     m_timeSeconds = seconds;
128 }
129
130 void RouteSegment::setTurnAngle(qreal degrees)
131 {
132     qDebug() << __PRETTY_FUNCTION__;
133
134     m_turnAngle = degrees;
135 }
136
137 void RouteSegment::setTurnType(QString type)
138 {
139     qDebug() << __PRETTY_FUNCTION__;
140
141     m_turnType = type;
142 }
143
144 QString RouteSegment::street() const
145 {
146     qDebug() << __PRETTY_FUNCTION__;
147
148     // regular expressions for matching/replacing instructions
149     const QString REGEXP_1ST_SEGMENT
150         = "^Head (north|northeast|east|southeast|south|southwest|west|northwest)";
151     const QString REGEXP_CONTINUE = "^Continue";
152     const QString REGEXP_ROUNDABOUT
153         = "^At the roundabout, take the \\d(st|nd|rd|th) exit";
154     const QString REGEXP_TURNS = "^(Turn|Slight|Sharp) (left|right)";
155     const QString REGEXP_U_TURN = "^Make a U-turn";
156
157     QString result = m_instruction;
158
159     // cut beginning of the instruction
160     // (but only if it matches with the expected value)
161
162     if (m_turnType == "") {
163         // first segment (without turn type code)
164         QRegExp regexp(REGEXP_1ST_SEGMENT);
165         result.replace(regexp, "");
166
167     } else if (m_turnType == "C") {
168         // continue straight
169         QRegExp regexp(REGEXP_CONTINUE);
170         result.replace(regexp, "");
171
172     } else if ((m_turnType == "TL") || (m_turnType == "TSLL")
173                || (m_turnType == "TSHL") || (m_turnType == "TR")
174                || (m_turnType == "TSLR") || (m_turnType == "TSHR")) {
175         // turns
176         QRegExp regexp(REGEXP_TURNS);
177         result.replace(regexp, "");
178
179     } else if (m_turnType == "TU") {
180         // u-turn
181         QRegExp regexp(REGEXP_U_TURN);
182         result.replace(regexp, "");
183
184     } else if (m_turnType.startsWith("EXIT")) {
185         // roundabout
186         QRegExp regexp(REGEXP_ROUNDABOUT);
187         result.replace(regexp, "");
188
189     } else {
190         // no match, parsing failed
191         qCritical() << __PRETTY_FUNCTION__ << "PARSING FAILED! ( turn type:"
192                     << m_turnType << "instruction:" << m_instruction << ")";
193     }
194
195     // replace on/at/onto words at the beginning of the result
196     // with zero or one leading space and one following space
197     QRegExp regexp("^ ?(on|at|onto) ");
198     result.replace(regexp, "");
199
200     return result;
201 }
202
203 int RouteSegment::time() const
204 {
205     qDebug() << __PRETTY_FUNCTION__;
206
207     return m_timeSeconds;
208 }
209
210 qreal RouteSegment::turnAngle() const
211 {
212     qDebug() << __PRETTY_FUNCTION__;
213
214     return m_turnAngle;
215 }
216
217 QString RouteSegment::turnType() const
218 {
219     qDebug() << __PRETTY_FUNCTION__;
220
221     return m_turnType;
222 }