Add Longitude and Latitude to StationListModel
[quandoparte] / application / stationlistmodel.cpp
1 /*
2
3 Copyright (C) 2011 Luciano Montanaro <mikelima@cirulla.net>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; see the file COPYING.  If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19
20 */
21
22 #include "stationlistmodel.h"
23
24 #include <QFile>
25 #include <QFileInfo>
26 #include <QDebug>
27 #include <QStandardItem>
28 #include <QGeoCoordinate>
29
30 #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
31 QTM_USE_NAMESPACE
32 Q_DECLARE_METATYPE(QGeoCoordinate)
33 #endif
34
35 StationListModel::StationListModel(QObject *parent) :
36     QStandardItemModel(parent)
37 {
38     setRowCount(0);
39 #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
40     setRoleNames(roleNames());
41 #endif
42 }
43
44 bool StationListModel::load(const QString &filename)
45 {
46     QFile file(filename);
47     QFileInfo fi(file);
48
49     qDebug() << "loading file:" << fi.absoluteFilePath();
50
51     emit layoutAboutToBeChanged();
52     beginResetModel();
53     if (!file.open(QFile::ReadOnly | QFile::Text)) {
54         qDebug() << "cannot open file:" << filename;
55         return false;
56     }
57     m_reader.setDevice(&file);
58     m_reader.readNext();
59     while (!m_reader.atEnd()) {
60         if (m_reader.isStartElement()) {
61             if(m_reader.name() == "stations") {
62                 readStationsElement();
63             } else {
64                 m_reader.raiseError(tr("Not a qpl file"));
65             }
66         } else {
67             m_reader.readNext();
68         }
69     }
70     file.close();
71     qDebug() << rowCount() << "stations loaded";
72     if (m_reader.hasError()) {
73         qDebug() << "parser error for:" << filename;
74         return false;
75     } else if (file.error() != QFile::NoError) {
76         qDebug() << "file error for:" << filename;
77         return false;
78     }
79     endResetModel();
80     emit layoutChanged();
81     return true;
82 }
83
84 QHash<int, QByteArray> StationListModel::roleNames() const
85 {
86     QHash<int, QByteArray> roles;
87     roles[Qt::DisplayRole] = "name";
88     roles[StationListModel::PositionRole] = "position";
89     roles[StationListModel::StationCodeRole] = "code";
90     roles[StationListModel::LongitudeRole] = "longitude";
91     roles[StationListModel::LatitudeRole] = "latitude";
92     return roles;
93 }
94
95 int StationListModel::rowCount(const QModelIndex &parent) const
96 {
97     return QStandardItemModel::rowCount(parent);
98
99 }
100
101 void StationListModel::readStationsElement()
102 {
103     m_reader.readNext();
104     while (!m_reader.atEnd()) {
105         if (m_reader.isEndElement()) {
106             m_reader.readNext();
107             break;
108         } else if (m_reader.isStartElement()) {
109             if (m_reader.name() == "station") {
110                 readStationElement();
111             } else {
112                 skipUnknownElement(m_reader.name().toString());
113             }
114         } else {
115             m_reader.readNext();
116         }
117     }
118 }
119
120 void StationListModel::readStationElement()
121 {
122     QStandardItem *item = new QStandardItem;
123     m_reader.readNext();
124     while (!m_reader.atEnd()) {
125         if (m_reader.isEndElement()) {
126             this->appendRow(item);
127             m_reader.readNext();
128             break;
129         } else if (m_reader.isStartElement()) {
130             if (m_reader.name() == "pos") {
131                 readPosElement(item);
132             } else  if (m_reader.name() == "name") {
133                 readNameElement(item);
134             } else  if (m_reader.name() == "code") {
135                 readCodeElement(item);
136             } else {
137                 skipUnknownElement(m_reader.name().toString());
138             }
139         } else {
140             m_reader.readNext();
141         }
142     }
143 }
144
145 void StationListModel::readPosElement(QStandardItem *item)
146 {
147     QStringList coordinates = m_reader.readElementText().split(",");
148     QGeoCoordinate pos = QGeoCoordinate(coordinates[0].toDouble(), coordinates[1].toDouble());
149     item->setData(QVariant::fromValue(pos), PositionRole);
150     item->setData(QVariant::fromValue(pos.longitude()), LongitudeRole);
151     item->setData(QVariant::fromValue(pos.latitude()), LatitudeRole);
152     m_reader.readElementText();
153     if (m_reader.isEndElement()) {
154         m_reader.readNext();
155     }
156 }
157
158 void StationListModel::readNameElement(QStandardItem *item)
159 {
160     item->setText(m_reader.readElementText());
161     if (m_reader.isEndElement()) {
162         m_reader.readNext();
163     }
164 }
165
166 void StationListModel::readCodeElement(QStandardItem *item)
167 {
168     const QString code = m_reader.readElementText();
169     qDebug() << "reading code element" << code;
170
171     item->setData(QVariant::fromValue(code), StationCodeRole);
172     if (m_reader.isEndElement()) {
173         m_reader.readNext();
174     }
175 }
176
177 void StationListModel::skipUnknownElement(const QString &name)
178 {
179     qDebug() << "skipping unknown element" << name << "at line" << m_reader.lineNumber();
180
181     m_reader.readNext();
182     while (!m_reader.atEnd()) {
183         if (m_reader.isEndElement()) {
184             m_reader.readNext();
185             break;
186         } else if (!m_reader.isStartElement()) {
187             skipUnknownElement(m_reader.name().toString());
188         } else {
189             m_reader.readNext();
190         }
191     }
192 }