Changes: parses comprehensive route data
[ptas] / zouba / src / route_p.cpp
1 #include "route_p.h"
2 #include "location.h"
3
4 #include <QXmlStreamReader>
5 #include <QDebug>
6 #include <QList>
7 #include <QFile>
8 #include <QStringList>
9
10 RoutePrivate::RoutePrivate( QObject *parent ) :
11     m_fromValid(false),
12     m_toValid(false),
13     m_fromLocation(0),
14     m_toLocation(0)
15 {
16   Q_UNUSED( parent )
17 }
18
19 RoutePrivate::~RoutePrivate()
20 {
21 }
22
23 QList<RouteData> RoutePrivate::parseReply( const QByteArray &reply )
24 {
25   qDebug() << "parsing route";
26
27   QList<RouteData> retVal;
28   RouteData routeData;
29   LegData legData;
30
31   QXmlStreamReader xml( reply );
32
33   QHash<QString, bool> in;
34   QHash<QString, bool> have;
35
36   QStringList haveKeys;
37   QStringList inKeys;
38
39   haveKeys
40     << "LINE"
41     << "TIME"
42     << "TRIP"
43     << "DEPARTURE"
44     << "ARRIVAL"
45     ;
46
47   inKeys
48     << "ROUTE"
49     << "LINE"
50     << "STOP"
51     << "WALK"
52     << "POINT"
53     ;
54
55   for ( int index=0; index<haveKeys.count(); ++index ) {
56     have[ haveKeys.at(index) ] = false;
57   }
58
59   for ( int index=0; index<inKeys.count(); ++index ) {
60     in[ inKeys.at(index) ] = false;
61   }
62
63   while ( !xml.atEnd() ) {
64     xml.readNext();
65
66     QString xmlName = xml.name().toString();
67
68     if ( xml.isStartElement() ) {
69       if ( inKeys.contains( xmlName ) ) {
70         in[ xmlName ] = true;
71         //qDebug() << "in[" << xmlName << "] = true";
72       }
73
74       if ( xmlName == "ROUTE" ) {
75         // reset the 'have' flags to false
76         QList<QString> haveKeys = have.uniqueKeys();
77         for ( int haveKeysIndex=0; haveKeysIndex<have.count(); ++haveKeysIndex ) {
78           QString thisKey = haveKeys[ haveKeysIndex ];
79           have[ thisKey ] = false;
80           //qDebug() << "have[" << thisKey << "] = false";
81         }
82       }
83
84       if ( xmlName == "WALK" ) {
85         legData.m_how = "WALK";
86         have[ "DEPARTURE" ] = false;
87         have[ "ARRIVAL" ]   = false;
88         have[ "LENGTH" ]    = false;
89       }
90
91       if ( xmlName == "LINE" ) {
92         legData.m_how = "LINE";
93         QString lineCode( xml.attributes().value("code").toString() );
94         legData.m_lineCode = parseJORECode( lineCode );
95         have[ "DEPARTURE" ] = false;
96         have[ "ARRIVAL" ]   = false;
97         have[ "LENGTH" ]    = false;
98       }
99     }
100
101     if ( xml.isEndElement() ) {
102       if ( inKeys.contains( xmlName ) ) {
103         in[ xmlName ] = false;
104         //qDebug() << "in[" << xmlName << "] = false";
105       }
106
107       if ( xmlName == "ROUTE" ) {
108         retVal.append( routeData );
109         routeData.clear();
110       }
111
112       if ( xmlName == "WALK" || xmlName == "LINE" ) {
113         routeData.m_legData.append( legData );
114         legData.clear();
115         have[ "LENGTH" ] = false;
116       }
117     }
118
119     if ( !have[ "ARRIVAL" ] && ( in[ "WALK" ] || in[ "LINE" ] ) && ( in[ "STOP" ] || in[ "POINT" ] ) && xml.isStartElement() && xmlName == "ARRIVAL" ) {
120       QString arrivalTime( xml.attributes().value("time").toString() );
121       legData.m_arrivalTime = arrivalTime.rightJustified(4).insert(2,":");
122
123       // don't set have[ "ARRIVAL" ] since we want the last one of many STOPs
124     }
125
126     if ( !have[ "DEPARTURE" ] && in[ "LINE" ] && in[ "STOP" ] && xml.isStartElement() && xmlName == "DEPARTURE" ) {
127       QString departureTime( xml.attributes().value("time").toString() );
128       legData.m_departureTime = departureTime.rightJustified(4).insert(2,":");
129
130       have[ "DEPARTURE" ] = true;
131     }
132
133     if ( !have[ "DEPARTURE" ] && in[ "WALK" ] && ( in[ "POINT" ] || in[ "STOP" ] ) && xml.isStartElement() && xmlName == "DEPARTURE" ) {
134       QString departureTime( xml.attributes().value("time").toString() );
135       legData.m_departureTime = departureTime.rightJustified(4).insert(2,":");
136
137       have[ "DEPARTURE" ] = true;
138     }
139
140     if ( !have[ "LENGTH" ] && ( in[ "WALK" ] || in[ "LINE" ] ) && xml.isStartElement() && xmlName == "LENGTH" ) {
141       legData.m_tripTime     = xml.attributes().value("time").toString();
142       legData.m_tripDistance = xml.attributes().value("dist").toString();
143
144       have[ "LENGTH" ] = true;
145     }
146
147     if ( !have[ "TRIP" ] && in[ "ROUTE" ] && xml.isStartElement() && xmlName == "LENGTH" ) {
148       routeData.m_tripTime     = xml.attributes().value("time").toString();
149       routeData.m_tripDistance = xml.attributes().value("dist").toString();
150
151       have[ "TRIP" ] = true;
152     }
153
154     if ( !have[ "LINE" ] && in[ "ROUTE" ] && xml.isStartElement() && xmlName == "LINE" ) {
155       QString lineCode( xml.attributes().value("code").toString() );
156
157       routeData.m_lineCode = parseJORECode( lineCode );
158       have[ "LINE" ] = true;
159     }
160
161     if ( !have[ "TIME" ] && in[ "ROUTE" ] && in[ "LINE" ] && in[ "STOP" ] && xmlName == "DEPARTURE" ) {
162       QString departureTime( xml.attributes().value("time").toString() );
163
164       routeData.m_departureTime = departureTime.rightJustified(4).insert(2,":");
165       have[ "TIME" ] = true;
166     }
167
168   }
169
170   if ( xml.hasError() ) {
171     qDebug() << "xml error:" << xml.errorString();
172   }
173
174   if ( retVal.isEmpty() ) {
175     qDebug() << "no routes found";
176   }
177
178   return retVal;
179 }
180
181 void RoutePrivate::setFromLocation( Location *location )
182 {
183   m_fromLocation = location;
184   m_fromValid = true;
185 }
186
187 Location *RoutePrivate::fromLocation() const
188 {
189   return m_fromLocation;
190 }
191
192 void RoutePrivate::setToLocation( Location *toLocation )
193 {
194   m_toLocation = toLocation;
195   m_toValid = true;
196 }
197
198 QString RoutePrivate::parseJORECode( const QString &joreCode ) const
199 {
200   QString retVal;
201
202   QString areaTransportTypeCode( joreCode.mid(0,1) );
203   QString lineCode( joreCode.mid(1,3) );
204   QString letterVariant( joreCode.mid(4,1) );
205   QString letterNumberVariant( joreCode.mid(5,1) );
206   QString direction( joreCode.mid(6,1) );
207
208   lineCode.setNum( lineCode.toInt() );
209
210   retVal = lineCode;
211
212   if ( letterVariant != " " ) {
213     retVal += letterVariant;
214   }
215
216   return retVal;
217 }
218
219 Location *RoutePrivate::toLocation() const
220 {
221   return m_toLocation;
222 }
223
224 bool RoutePrivate::fromValid()
225 {
226   return m_fromValid;
227 }
228
229 bool RoutePrivate::toValid()
230 {
231   return m_toValid;
232 }