Incorporated changes from bus project.
[ptas] / src / xmlparser.cpp
1 #include "xmlparser.h"
2 #include "routedata.h"
3
4 #include <QList>
5 #include <QByteArray>
6 #include <QStringRef>
7 #include <QString>
8 #include <QStringList>
9 #include <QXmlStreamReader>
10 #include <QDebug>
11
12 XmlParser::XmlParser()
13 {
14 }
15
16 QList<XmlParser::LocsData> XmlParser::parseLocs(QXmlStreamReader &xml)
17 {
18     QList<XmlParser::LocsData> retVal;
19     retVal.clear();
20
21     QSet<QString> elements;
22     elements
23             << "coord"
24             << "x"
25             << "y"
26             << "arrTime"
27             << "depTime"
28             << "name";
29
30     QString name;
31
32     while (xml.readNextStartElement()) {
33         QHash<QString,QString> text;
34
35         while (xml.readNextStartElement()) {
36             if (xml.name() == "coord") {
37                 xml.readNextStartElement();
38                 // x
39                 text.insert(xml.name().toString(),xml.readElementText());
40
41                 xml.readNextStartElement();
42                 // y
43                 text.insert(xml.name().toString(),xml.readElementText());
44
45                 xml.readNextStartElement(); // up a level
46             } else {
47                 text.insert(xml.name().toString(),xml.readElementText());
48             }
49         }
50
51         LocsData data;
52         data.m_x = text.value("x");
53         data.m_y = text.value("y");
54         data.m_arrTime = text.value("arrTime");
55         data.m_depTime = text.value("depTime");
56         data.m_name = text.value("name");
57
58         retVal << data;
59     }
60
61     return retVal;
62 }
63
64 QList<LegData> XmlParser::parseLegs(QXmlStreamReader &xml)
65 {
66     QList<LegData> retVal;
67
68     while (xml.readNextStartElement()) { // loop over leg <node>s
69         QString how;
70         QString tripTime;
71         QString tripDistance;
72         QString departureTime;
73         QString arrivalTime;
74         QString lineCode;
75
76         if (xml.name() == "node") { // new leg
77             xml.readNextStartElement();
78
79             if (xml.name() == "length") {
80                 tripDistance = xml.readElementText();
81             }
82
83             xml.readNextStartElement();
84
85             if (xml.name() == "duration") {
86                 tripTime = xml.readElementText();
87             }
88
89             xml.readNextStartElement();
90
91             if (xml.name() == "type") {
92                 how = parseType(xml.readElementText());
93             }
94
95             xml.readNextStartElement();
96
97             if (xml.name() == "code") { // only if type != walk
98                 lineCode = xml.readElementText();
99
100                 xml.readNextStartElement();
101             }
102
103             if (xml.name() == "locs") {
104                 QList<LocsData> locs = parseLocs(xml);
105                 arrivalTime = parseTime(locs[0].m_arrTime);
106                 departureTime = parseTime(locs[0].m_depTime);
107
108                 LegData legData;
109
110                 legData.m_arrivalTime = arrivalTime;
111                 legData.m_departureTime = departureTime;
112                 legData.m_how = how;
113                 legData.m_lineCode = parseJORECode(lineCode);
114                 legData.m_tripDistance = tripDistance;
115                 legData.m_tripTime = tripTime;
116
117                 retVal << legData;
118
119                 xml.skipCurrentElement();
120             }
121         }
122     }
123
124     return retVal;
125 }
126
127 QList<RouteData> XmlParser::parseRouteData(const QByteArray &reply)
128 {
129     QList<RouteData> retVal;
130
131     QXmlStreamReader xml(reply);
132
133     // find response
134     while (!xml.atEnd()) {
135         xml.readNext();
136
137         if (xml.name() == "response") {
138
139             while (xml.readNextStartElement()) { // loop over route <node>
140                 RouteData routeData;
141
142                 if (xml.name() == "node") { // ROUTE node
143
144                     xml.readNextStartElement(); // redundant single <node>
145
146                     xml.readNextStartElement();
147
148                     if (xml.name() == "length") {
149                         routeData.m_tripDistance = xml.readElementText();
150                     }
151
152                     xml.readNextStartElement();
153
154                     if (xml.name() == "duration") {
155                         routeData.m_tripTime = xml.readElementText();
156                     }
157
158                     xml.readNextStartElement();
159
160                     if (xml.name() == "legs") {
161                         QList<LegData> legData = parseLegs(xml);
162
163                         foreach (LegData thisLeg, legData) {
164                             // set the departure time of the Route to the departure time of the
165                             // first non-walk (usually the bus)
166                             if (thisLeg.m_how != "walk" && routeData.m_departureTime.isEmpty()) {
167                                 routeData.m_departureTime = thisLeg.m_departureTime;
168                                 routeData.m_lineCode = thisLeg.m_lineCode;
169                             }
170
171                             routeData << thisLeg;
172                         }
173
174                         xml.skipCurrentElement();
175                     }
176                 }
177
178                 retVal << routeData;
179                 routeData.clear();
180
181                 xml.readNext();
182             }
183         }
184     }
185
186     if (xml.hasError()) {
187         qDebug() << "xml error:" << xml.errorString();
188     }
189
190     return retVal;
191 }
192
193 QPair<QString,QString> XmlParser::parseGeocode(const QByteArray &reply)
194 {
195     QPair<QString,QString> retVal;
196
197     m_error = false;
198
199     QXmlStreamReader xml(reply);
200
201     while (!xml.atEnd()) {
202         xml.readNext();
203
204         if (xml.name() == "coords") {
205             QString text(xml.readElementText());
206
207             QStringList coords(text.split(","));
208
209             QString newLongitude(coords.at(0));
210             QString newLatitude(coords.at(1));
211
212             retVal.first  = newLongitude;
213             retVal.second = newLatitude;
214
215             break;
216         }
217
218         if (xml.name() == "ERROR") {
219             qDebug() << "ERROR";
220             m_error = true;
221         }
222     }
223
224     if (m_error) {
225         qDebug() << "xml error";
226     }
227
228     return retVal;
229 }
230
231 QString XmlParser::parseJORECode(const QString &joreCode) const
232 {
233     QString retVal;
234
235     QString areaTransportTypeCode(joreCode.mid(0,1));
236     QString lineCode(joreCode.mid(1,3));
237     QString letterVariant(joreCode.mid(4,1));
238     QString letterNumberVariant(joreCode.mid(5,1));
239     QString direction(joreCode.mid(6,1));
240
241     Q_UNUSED(areaTransportTypeCode);
242     Q_UNUSED(letterNumberVariant);
243     Q_UNUSED(direction);
244
245     lineCode.setNum(lineCode.toInt());
246
247     retVal = lineCode;
248
249     if (letterVariant != " ") {
250         retVal += letterVariant;
251     }
252
253     return retVal;
254 }
255
256 QString XmlParser::parseTime(const QString &time) const
257 {
258     QString retVal = time.right(4).insert(2,":");
259
260     return retVal;
261 }
262
263 QString XmlParser::parseType(const QString &type) const
264 {
265     QString retVal;
266     QStringList transportType;
267     transportType
268             << "Helsi"
269             << "Trams"
270             << "Espoo"
271             << "Vanta"
272             << "Regio"
273             << "Metro"
274             << "Ferry"
275             << "ULine"
276             << "CTrai"
277             << "HelSe"
278             << "HelNi"
279             << "EspSe"
280             << "VanSe"
281             << "RegNi"
282             << "Kirkk"
283             << "Kerav"
284                ;
285
286     if (type=="walk") {
287         retVal = "walk";
288     } else {
289         retVal = transportType.at(type.toInt()-1);
290     }
291
292     return retVal;
293 }