2016-10-23 11:09:20 +02:00
|
|
|
#include "tcxparser.h"
|
|
|
|
|
|
|
|
|
2016-10-27 09:15:05 +02:00
|
|
|
qreal TCXParser::number()
|
|
|
|
{
|
|
|
|
bool res;
|
|
|
|
qreal ret = _reader.readElementText().toDouble(&res);
|
|
|
|
if (!res)
|
|
|
|
_reader.raiseError(QString("Invalid %1.").arg(
|
|
|
|
_reader.name().toString()));
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
QDateTime TCXParser::time()
|
|
|
|
{
|
|
|
|
QDateTime d = QDateTime::fromString(_reader.readElementText(),
|
|
|
|
Qt::ISODate);
|
|
|
|
if (!d.isValid())
|
|
|
|
_reader.raiseError(QString("Invalid %1.").arg(
|
|
|
|
_reader.name().toString()));
|
|
|
|
|
|
|
|
return d;
|
|
|
|
}
|
|
|
|
|
2016-10-24 00:21:40 +02:00
|
|
|
Coordinates TCXParser::position()
|
2016-10-23 11:09:20 +02:00
|
|
|
{
|
2016-10-24 00:21:40 +02:00
|
|
|
Coordinates pos;
|
|
|
|
qreal val;
|
|
|
|
bool res;
|
2016-10-23 11:09:20 +02:00
|
|
|
|
|
|
|
while (_reader.readNextStartElement()) {
|
2016-10-24 00:21:40 +02:00
|
|
|
if (_reader.name() == "LatitudeDegrees") {
|
|
|
|
val = _reader.readElementText().toDouble(&res);
|
|
|
|
if (!res || (val < -90.0 || val > 90.0))
|
2016-10-27 09:15:05 +02:00
|
|
|
_reader.raiseError("Invalid LatitudeDegrees.");
|
2016-10-24 00:21:40 +02:00
|
|
|
else
|
2016-10-24 00:51:19 +02:00
|
|
|
pos.setLat(val);
|
2016-10-24 00:21:40 +02:00
|
|
|
} else if (_reader.name() == "LongitudeDegrees") {
|
|
|
|
val = _reader.readElementText().toDouble(&res);
|
|
|
|
if (!res || (val < -180.0 || val > 180.0))
|
2016-10-27 09:15:05 +02:00
|
|
|
_reader.raiseError("Invalid LongitudeDegrees.");
|
2016-10-24 00:21:40 +02:00
|
|
|
else
|
2016-10-24 00:51:19 +02:00
|
|
|
pos.setLon(val);
|
2016-10-24 00:21:40 +02:00
|
|
|
} else
|
2016-10-23 11:09:20 +02:00
|
|
|
_reader.skipCurrentElement();
|
|
|
|
}
|
|
|
|
|
|
|
|
return pos;
|
|
|
|
}
|
|
|
|
|
2016-10-27 09:15:05 +02:00
|
|
|
void TCXParser::trackpointData(Trackpoint &trackpoint)
|
2016-10-23 11:09:20 +02:00
|
|
|
{
|
|
|
|
while (_reader.readNextStartElement()) {
|
|
|
|
if (_reader.name() == "Position")
|
2016-10-27 09:15:05 +02:00
|
|
|
trackpoint.setCoordinates(position());
|
2016-10-23 11:09:20 +02:00
|
|
|
else if (_reader.name() == "AltitudeMeters")
|
2016-10-27 09:15:05 +02:00
|
|
|
trackpoint.setElevation(number());
|
2016-10-23 11:09:20 +02:00
|
|
|
else if (_reader.name() == "Time")
|
2016-10-27 09:15:05 +02:00
|
|
|
trackpoint.setTimestamp(time());
|
2016-10-23 11:09:20 +02:00
|
|
|
else if (_reader.name() == "HeartRateBpm")
|
2016-10-27 09:15:05 +02:00
|
|
|
trackpoint.setHeartRate(number());
|
2016-10-23 11:09:20 +02:00
|
|
|
else
|
|
|
|
_reader.skipCurrentElement();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-27 09:15:05 +02:00
|
|
|
void TCXParser::waypointData(Waypoint &waypoint)
|
2016-10-23 11:09:20 +02:00
|
|
|
{
|
|
|
|
while (_reader.readNextStartElement()) {
|
|
|
|
if (_reader.name() == "Position")
|
2016-10-27 09:15:05 +02:00
|
|
|
waypoint.setCoordinates(position());
|
2016-10-23 11:09:20 +02:00
|
|
|
else if (_reader.name() == "Name")
|
2016-10-27 09:15:05 +02:00
|
|
|
waypoint.setName(_reader.readElementText());
|
2016-10-23 11:09:20 +02:00
|
|
|
else if (_reader.name() == "Notes")
|
2016-10-27 09:15:05 +02:00
|
|
|
waypoint.setDescription(_reader.readElementText());
|
2016-10-23 11:09:20 +02:00
|
|
|
else if (_reader.name() == "AltitudeMeters")
|
2016-10-27 09:15:05 +02:00
|
|
|
waypoint.setElevation(number());
|
2016-10-23 11:09:20 +02:00
|
|
|
else if (_reader.name() == "Time")
|
2016-10-27 09:15:05 +02:00
|
|
|
waypoint.setTimestamp(time());
|
2016-10-23 11:09:20 +02:00
|
|
|
else
|
|
|
|
_reader.skipCurrentElement();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-27 09:15:05 +02:00
|
|
|
void TCXParser::trackpoints(QVector<Trackpoint> &track)
|
2016-10-23 11:09:20 +02:00
|
|
|
{
|
|
|
|
while (_reader.readNextStartElement()) {
|
|
|
|
if (_reader.name() == "Trackpoint") {
|
2016-10-27 09:15:05 +02:00
|
|
|
track.append(Trackpoint());
|
|
|
|
trackpointData(track.back());
|
2016-10-23 11:09:20 +02:00
|
|
|
} else
|
|
|
|
_reader.skipCurrentElement();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TCXParser::lap()
|
|
|
|
{
|
|
|
|
while (_reader.readNextStartElement()) {
|
|
|
|
if (_reader.name() == "Track") {
|
|
|
|
_tracks.append(QVector<Trackpoint>());
|
2016-10-27 09:15:05 +02:00
|
|
|
trackpoints(_tracks.back());
|
2016-10-23 11:09:20 +02:00
|
|
|
} else
|
|
|
|
_reader.skipCurrentElement();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TCXParser::course()
|
|
|
|
{
|
|
|
|
while (_reader.readNextStartElement()) {
|
|
|
|
if (_reader.name() == "Track") {
|
2016-10-28 00:48:04 +02:00
|
|
|
_tracks.append(QVector<Trackpoint>());
|
|
|
|
trackpoints(_tracks.back());
|
2016-10-23 11:09:20 +02:00
|
|
|
} else if (_reader.name() == "CoursePoint") {
|
2016-10-27 09:15:05 +02:00
|
|
|
_waypoints.append(Waypoint());
|
|
|
|
waypointData(_waypoints.back());
|
2016-10-23 11:09:20 +02:00
|
|
|
} else
|
|
|
|
_reader.skipCurrentElement();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TCXParser::activity()
|
|
|
|
{
|
|
|
|
while (_reader.readNextStartElement()) {
|
|
|
|
if (_reader.name() == "Lap")
|
|
|
|
lap();
|
|
|
|
else
|
|
|
|
_reader.skipCurrentElement();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TCXParser::courses()
|
|
|
|
{
|
|
|
|
while (_reader.readNextStartElement()) {
|
|
|
|
if (_reader.name() == "Course")
|
|
|
|
course();
|
|
|
|
else
|
|
|
|
_reader.skipCurrentElement();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TCXParser::activities()
|
|
|
|
{
|
|
|
|
while (_reader.readNextStartElement()) {
|
|
|
|
if (_reader.name() == "Activity")
|
|
|
|
activity();
|
|
|
|
else
|
|
|
|
_reader.skipCurrentElement();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TCXParser::tcx()
|
|
|
|
{
|
|
|
|
while (_reader.readNextStartElement()) {
|
|
|
|
if (_reader.name() == "Courses")
|
|
|
|
courses();
|
|
|
|
else if (_reader.name() == "Activities")
|
|
|
|
activities();
|
|
|
|
else
|
|
|
|
_reader.skipCurrentElement();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TCXParser::parse()
|
|
|
|
{
|
|
|
|
if (_reader.readNextStartElement()) {
|
|
|
|
if (_reader.name() == "TrainingCenterDatabase")
|
|
|
|
tcx();
|
|
|
|
else
|
|
|
|
_reader.raiseError("Not a TCX file.");
|
|
|
|
}
|
|
|
|
|
|
|
|
return !_reader.error();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TCXParser::loadFile(QIODevice *device)
|
|
|
|
{
|
|
|
|
_reader.clear();
|
|
|
|
_reader.setDevice(device);
|
|
|
|
|
|
|
|
return parse();
|
|
|
|
}
|