Incorporated changes from bus project.
[ptas] / src / xmlparser.cpp
diff --git a/src/xmlparser.cpp b/src/xmlparser.cpp
new file mode 100644 (file)
index 0000000..7e82322
--- /dev/null
@@ -0,0 +1,293 @@
+#include "xmlparser.h"
+#include "routedata.h"
+
+#include <QList>
+#include <QByteArray>
+#include <QStringRef>
+#include <QString>
+#include <QStringList>
+#include <QXmlStreamReader>
+#include <QDebug>
+
+XmlParser::XmlParser()
+{
+}
+
+QList<XmlParser::LocsData> XmlParser::parseLocs(QXmlStreamReader &xml)
+{
+    QList<XmlParser::LocsData> retVal;
+    retVal.clear();
+
+    QSet<QString> elements;
+    elements
+            << "coord"
+            << "x"
+            << "y"
+            << "arrTime"
+            << "depTime"
+            << "name";
+
+    QString name;
+
+    while (xml.readNextStartElement()) {
+        QHash<QString,QString> text;
+
+        while (xml.readNextStartElement()) {
+            if (xml.name() == "coord") {
+                xml.readNextStartElement();
+                // x
+                text.insert(xml.name().toString(),xml.readElementText());
+
+                xml.readNextStartElement();
+                // y
+                text.insert(xml.name().toString(),xml.readElementText());
+
+                xml.readNextStartElement(); // up a level
+            } else {
+                text.insert(xml.name().toString(),xml.readElementText());
+            }
+        }
+
+        LocsData data;
+        data.m_x = text.value("x");
+        data.m_y = text.value("y");
+        data.m_arrTime = text.value("arrTime");
+        data.m_depTime = text.value("depTime");
+        data.m_name = text.value("name");
+
+        retVal << data;
+    }
+
+    return retVal;
+}
+
+QList<LegData> XmlParser::parseLegs(QXmlStreamReader &xml)
+{
+    QList<LegData> retVal;
+
+    while (xml.readNextStartElement()) { // loop over leg <node>s
+        QString how;
+        QString tripTime;
+        QString tripDistance;
+        QString departureTime;
+        QString arrivalTime;
+        QString lineCode;
+
+        if (xml.name() == "node") { // new leg
+            xml.readNextStartElement();
+
+            if (xml.name() == "length") {
+                tripDistance = xml.readElementText();
+            }
+
+            xml.readNextStartElement();
+
+            if (xml.name() == "duration") {
+                tripTime = xml.readElementText();
+            }
+
+            xml.readNextStartElement();
+
+            if (xml.name() == "type") {
+                how = parseType(xml.readElementText());
+            }
+
+            xml.readNextStartElement();
+
+            if (xml.name() == "code") { // only if type != walk
+                lineCode = xml.readElementText();
+
+                xml.readNextStartElement();
+            }
+
+            if (xml.name() == "locs") {
+                QList<LocsData> locs = parseLocs(xml);
+                arrivalTime = parseTime(locs[0].m_arrTime);
+                departureTime = parseTime(locs[0].m_depTime);
+
+                LegData legData;
+
+                legData.m_arrivalTime = arrivalTime;
+                legData.m_departureTime = departureTime;
+                legData.m_how = how;
+                legData.m_lineCode = parseJORECode(lineCode);
+                legData.m_tripDistance = tripDistance;
+                legData.m_tripTime = tripTime;
+
+                retVal << legData;
+
+                xml.skipCurrentElement();
+            }
+        }
+    }
+
+    return retVal;
+}
+
+QList<RouteData> XmlParser::parseRouteData(const QByteArray &reply)
+{
+    QList<RouteData> retVal;
+
+    QXmlStreamReader xml(reply);
+
+    // find response
+    while (!xml.atEnd()) {
+        xml.readNext();
+
+        if (xml.name() == "response") {
+
+            while (xml.readNextStartElement()) { // loop over route <node>
+                RouteData routeData;
+
+                if (xml.name() == "node") { // ROUTE node
+
+                    xml.readNextStartElement(); // redundant single <node>
+
+                    xml.readNextStartElement();
+
+                    if (xml.name() == "length") {
+                        routeData.m_tripDistance = xml.readElementText();
+                    }
+
+                    xml.readNextStartElement();
+
+                    if (xml.name() == "duration") {
+                        routeData.m_tripTime = xml.readElementText();
+                    }
+
+                    xml.readNextStartElement();
+
+                    if (xml.name() == "legs") {
+                        QList<LegData> legData = parseLegs(xml);
+
+                        foreach (LegData thisLeg, legData) {
+                            // set the departure time of the Route to the departure time of the
+                            // first non-walk (usually the bus)
+                            if (thisLeg.m_how != "walk" && routeData.m_departureTime.isEmpty()) {
+                                routeData.m_departureTime = thisLeg.m_departureTime;
+                                routeData.m_lineCode = thisLeg.m_lineCode;
+                            }
+
+                            routeData << thisLeg;
+                        }
+
+                        xml.skipCurrentElement();
+                    }
+                }
+
+                retVal << routeData;
+                routeData.clear();
+
+                xml.readNext();
+            }
+        }
+    }
+
+    if (xml.hasError()) {
+        qDebug() << "xml error:" << xml.errorString();
+    }
+
+    return retVal;
+}
+
+QPair<QString,QString> XmlParser::parseGeocode(const QByteArray &reply)
+{
+    QPair<QString,QString> retVal;
+
+    m_error = false;
+
+    QXmlStreamReader xml(reply);
+
+    while (!xml.atEnd()) {
+        xml.readNext();
+
+        if (xml.name() == "coords") {
+            QString text(xml.readElementText());
+
+            QStringList coords(text.split(","));
+
+            QString newLongitude(coords.at(0));
+            QString newLatitude(coords.at(1));
+
+            retVal.first  = newLongitude;
+            retVal.second = newLatitude;
+
+            break;
+        }
+
+        if (xml.name() == "ERROR") {
+            qDebug() << "ERROR";
+            m_error = true;
+        }
+    }
+
+    if (m_error) {
+        qDebug() << "xml error";
+    }
+
+    return retVal;
+}
+
+QString XmlParser::parseJORECode(const QString &joreCode) const
+{
+    QString retVal;
+
+    QString areaTransportTypeCode(joreCode.mid(0,1));
+    QString lineCode(joreCode.mid(1,3));
+    QString letterVariant(joreCode.mid(4,1));
+    QString letterNumberVariant(joreCode.mid(5,1));
+    QString direction(joreCode.mid(6,1));
+
+    Q_UNUSED(areaTransportTypeCode);
+    Q_UNUSED(letterNumberVariant);
+    Q_UNUSED(direction);
+
+    lineCode.setNum(lineCode.toInt());
+
+    retVal = lineCode;
+
+    if (letterVariant != " ") {
+        retVal += letterVariant;
+    }
+
+    return retVal;
+}
+
+QString XmlParser::parseTime(const QString &time) const
+{
+    QString retVal = time.right(4).insert(2,":");
+
+    return retVal;
+}
+
+QString XmlParser::parseType(const QString &type) const
+{
+    QString retVal;
+    QStringList transportType;
+    transportType
+            << "Helsi"
+            << "Trams"
+            << "Espoo"
+            << "Vanta"
+            << "Regio"
+            << "Metro"
+            << "Ferry"
+            << "ULine"
+            << "CTrai"
+            << "HelSe"
+            << "HelNi"
+            << "EspSe"
+            << "VanSe"
+            << "RegNi"
+            << "Kirkk"
+            << "Kerav"
+               ;
+
+    if (type=="walk") {
+        retVal = "walk";
+    } else {
+        retVal = transportType.at(type.toInt()-1);
+    }
+
+    return retVal;
+}