1 /****************************************************************************
3 ** Copyright (C) 2011 Tito Eritja Real <jtitoo@gmail.com>
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 3 of the License, or
8 ** (at your option) any later version.
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
13 ** GNU General Public License for more details.
15 ** You should have received a copy of the GNU General Public License
16 ** along with this program. If not, see <http://www.gnu.org/licenses/>.
18 ****************************************************************************/
21 #include "constants.h"
25 #include <QXmlStreamReader>
27 uint qHash(const QPoint& p)
29 return p.x() * 17 ^ p.y();
33 qreal max(qreal a, qreal b){
41 qreal min(qreal a, qreal b){
49 QString stringDateFromSeconds(qreal amount){
53 int hours = static_cast<int>(amount/3600);
54 int minutes = static_cast<int>((static_cast<int>(amount)%3600)/60);
55 int seconds = (static_cast<int>(amount)%3600)%60;
57 QString dateString=QString("%1h %2m %3s").arg(hours).arg(minutes).arg(seconds);
59 //qDebug()<<"amount " << amount << " seconds has been transformated to:" << dateString;
63 qreal toRad(qreal degrees){
64 qreal radians = degrees*PI/180;
68 Track* readFromXML(QString fileName){
70 // I need this function to work by now, When I've time I've to make it proper
71 // It doesn't work with no valid XML files!!!
73 QFile* file= new QFile(fileName);
76 qDebug() << "going to read file:" << fileName;
78 Track* myTrack = new Track(fileName);
79 myTrack->addActivity("doesn'tmatter");
81 if (!file->open(QIODevice::ReadOnly | QIODevice::Text)) {
82 qDebug() << "Error: Cannot read file "
83 << qPrintable(fileName) << ": "
84 << qPrintable(file->errorString());
90 if(fileName.endsWith(".tcx",Qt::CaseInsensitive)){
92 }else if(fileName.endsWith(".gpx",Qt::CaseInsensitive)){
95 qDebug()<<"Error: XML not recognized. " << "nameFile:" << fileName;
98 QXmlStreamReader xml(file);
100 while (!xml.atEnd() && !xml.hasError()) {
102 /* Read next element.*/
103 QXmlStreamReader::TokenType token = xml.readNext();
104 /* If token is just StartDocument, we'll go to next.*/
105 if(token == QXmlStreamReader::StartDocument) {
108 /* If token is StartElement, we'll see if we can read it.*/
109 if(token == QXmlStreamReader::StartElement) {
110 // just read Positions, dont care about nothing more...
111 // this means, all activities, laps or track sequences are
112 // processed as a single one!
114 if(fileType==XMLFile_GPX){
115 if(xml.name() == "trkpt") {
116 GpsPoint* point = parseGPXGpsPoint(xml);
117 //qDebug()<<"adding point: " << point->toString();
118 myTrack->addPoint(point);
122 }else if(fileType==XMLFile_TCX){
123 if(xml.name() == "Trackpoint") {
124 GpsPoint* point = parseTCXGpsPoint(xml);
125 //qDebug()<<"adding point: " << point->toString();
126 myTrack->addPoint(point);
132 if(xml.name()=="name"){
133 myTrack->setName(parseStringElement(xml,"name"));
136 if(xml.name()=="Activity" && !nameFound){
138 myTrack->setName(parseAttribute(xml,"Activity","Sport"));
143 /* Error handling. */
145 qDebug() << "Error: in readFromXML "
146 << qPrintable(fileName) << ": "
147 << qPrintable(file->errorString());
149 /* Removes any device() or data from the reader
150 * and resets its internal state to the initial state. */
151 qDebug()<<"clearing xml!";
153 qDebug() << "going to return myTrack";
157 qreal parseDoubleAttribute(QXmlStreamReader& xml, const char* stringElement, const char* stringAttribute){
158 QString sValue = parseAttribute(xml,stringElement,stringAttribute);
159 return sValue.toDouble();
162 QString parseAttribute(QXmlStreamReader& xml, const char* stringElement, const char* stringAttribute){
164 QString value = QString();
165 if(xml.tokenType() == QXmlStreamReader::StartElement && (xml.name() == stringElement)) {
166 // Let's get the attributes
167 QXmlStreamAttributes attributes = xml.attributes();
168 // Let's check that element has the attribute
169 if(attributes.hasAttribute(stringAttribute)) {
170 value.append(attributes.value(stringAttribute).toString());
176 QString parseStringElement(QXmlStreamReader& xml,const char* stringElement){
178 // It is suposed the XML is valid!
179 QString value = QString();
180 if(xml.tokenType() == QXmlStreamReader::StartElement && (xml.name() == stringElement)) {
181 /* We've found the element */
184 if(xml.tokenType() == QXmlStreamReader::Characters) {
186 value.append(xml.text().toString());
192 qreal parseDoubleElement(QXmlStreamReader& xml,const char* stringElement){
193 // It is suposed the XML is valid!
195 if(xml.tokenType() == QXmlStreamReader::StartElement && (xml.name() == stringElement)) {
196 /* We've found the element */
199 if(xml.tokenType() == QXmlStreamReader::Characters) {
200 /* Now we can add it to the point.*/
201 QString valueString = xml.text().toString();
202 value=valueString.toDouble();
208 QDateTime parseDateElement(QXmlStreamReader& xml,const char* stringElement){
209 // It is suposed the XML is valid!
211 if(xml.tokenType() == QXmlStreamReader::StartElement && (xml.name() == stringElement)) {
212 /* We've found the element */
215 if(xml.tokenType() == QXmlStreamReader::Characters) {
216 /* Now we can add it to the point.*/
217 QString valueString = xml.text().toString();
218 value = QDateTime::fromString(valueString,XML_DATE_FORMAT);
225 GpsPoint* parseGPXGpsPoint(QXmlStreamReader& xml){
226 GpsPoint* point = new GpsPoint(0,0,0);
227 /* Let's check that we're really getting a Trackpoint. */
228 if(xml.tokenType() != QXmlStreamReader::StartElement &&
229 xml.name() == "trkpt") {
232 // Let's take latitude and longitude attributes.
234 point->setLatitude(parseDoubleAttribute(xml,"trkpt","lat"));
235 point->setLongitude(parseDoubleAttribute(xml,"trkpt","lon"));
239 while(!(xml.tokenType() == QXmlStreamReader::EndElement &&
240 xml.name() == "trkpt")){
242 if(xml.tokenType() == QXmlStreamReader::StartElement) {
244 if(xml.name() == "ele"){
245 //qDebug()<<"found ele element";
246 point->setElevation(parseDoubleElement(xml,"ele"));
248 if(xml.name() == "time"){
249 point->setTime(parseDateElement(xml,"time"));
250 //qDebug()<<"found Trackpoint element";
258 GpsPoint* parseTCXGpsPoint(QXmlStreamReader& xml){
260 GpsPoint* point = new GpsPoint(0,0,0);
261 /* Let's check that we're really getting a Trackpoint. */
262 if(xml.tokenType() != QXmlStreamReader::StartElement &&
263 xml.name() == "Trackpoint") {
269 while(!(xml.tokenType() == QXmlStreamReader::EndElement &&
270 xml.name() == "Trackpoint")){
272 if(xml.tokenType() == QXmlStreamReader::StartElement) {
274 if(xml.name() == "Time"){
275 //qDebug()<<"found Time element";
276 point->setTime(parseDateElement(xml,"Time"));
278 if(xml.name() == "Position"){
279 //qDebug()<<"found Position element";
281 while(!(xml.tokenType() == QXmlStreamReader::EndElement &&
282 xml.name() == "Position")){
283 if(xml.tokenType()==QXmlStreamReader::StartElement && xml.name() == "LongitudeDegrees"){
284 //qDebug()<<"found LongitudeDegrees element";
285 point->setLongitude(parseDoubleElement(xml,"LongitudeDegrees"));
286 }if(xml.tokenType()==QXmlStreamReader::StartElement && xml.name() == "LatitudeDegrees"){
287 //qDebug()<<"found LatitudeDegrees element";
288 point->setLatitude(parseDoubleElement(xml,"LatitudeDegrees"));
291 //qDebug()<<"element readed: " << xml.name();
294 if(xml.tokenType()==QXmlStreamReader::StartElement && xml.name() == "AltitudeMeters"){
295 point->setElevation(parseDoubleElement(xml,"AltitudeMeters"));
296 //qDebug()<<"found Trackpoint element";
298 if(xml.tokenType()==QXmlStreamReader::StartElement && xml.name() == "DistanceMeters"){
299 point->setDistancePrev(parseDoubleElement(xml,"DistanceMeters"));
300 //qDebug()<<"found Trackpoint element";
308 QString nameFromFile(QString fileName){
311 int indexName = fileName.lastIndexOf(sep);
315 int cont = fileName.length()-indexName-1;
316 QString stringName = fileName.right(cont);