2016-10-23 11:09:20 +02:00
|
|
|
#include "tcxparser.h"
|
|
|
|
|
|
|
|
|
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))
|
|
|
|
_reader.raiseError("Invalid latitude.");
|
|
|
|
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))
|
|
|
|
_reader.raiseError("Invalid longitude.");
|
|
|
|
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-24 00:51:19 +02:00
|
|
|
void TCXParser::trackpointData(Trackpoint &t)
|
2016-10-23 11:09:20 +02:00
|
|
|
{
|
|
|
|
while (_reader.readNextStartElement()) {
|
|
|
|
if (_reader.name() == "Position")
|
2016-10-24 00:51:19 +02:00
|
|
|
t.setCoordinates(position());
|
2016-10-23 11:09:20 +02:00
|
|
|
else if (_reader.name() == "AltitudeMeters")
|
2016-10-24 00:51:19 +02:00
|
|
|
t.setElevation(_reader.readElementText().toDouble());
|
2016-10-23 11:09:20 +02:00
|
|
|
else if (_reader.name() == "Time")
|
2016-10-24 00:51:19 +02:00
|
|
|
t.setTimestamp(QDateTime::fromString(_reader.readElementText(),
|
|
|
|
Qt::ISODate));
|
2016-10-23 11:09:20 +02:00
|
|
|
else if (_reader.name() == "HeartRateBpm")
|
2016-10-24 00:51:19 +02:00
|
|
|
t.setHeartRate(_reader.readElementText().toDouble());
|
2016-10-23 11:09:20 +02:00
|
|
|
else
|
|
|
|
_reader.skipCurrentElement();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-24 00:51:19 +02:00
|
|
|
void TCXParser::routepointData(Waypoint &w)
|
2016-10-23 11:09:20 +02:00
|
|
|
{
|
|
|
|
while (_reader.readNextStartElement()) {
|
|
|
|
if (_reader.name() == "Position")
|
2016-10-24 00:51:19 +02:00
|
|
|
w.setCoordinates(position());
|
2016-10-23 11:09:20 +02:00
|
|
|
else if (_reader.name() == "AltitudeMeters")
|
2016-10-24 00:51:19 +02:00
|
|
|
w.setElevation(_reader.readElementText().toDouble());
|
2016-10-23 11:09:20 +02:00
|
|
|
else if (_reader.name() == "Time")
|
2016-10-24 00:51:19 +02:00
|
|
|
w.setTimestamp(QDateTime::fromString(_reader.readElementText(),
|
|
|
|
Qt::ISODate));
|
2016-10-23 11:09:20 +02:00
|
|
|
else
|
|
|
|
_reader.skipCurrentElement();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-24 00:51:19 +02:00
|
|
|
void TCXParser::waypointData(Waypoint &w)
|
2016-10-23 11:09:20 +02:00
|
|
|
{
|
|
|
|
while (_reader.readNextStartElement()) {
|
|
|
|
if (_reader.name() == "Position")
|
2016-10-24 00:51:19 +02:00
|
|
|
w.setCoordinates(position());
|
2016-10-23 11:09:20 +02:00
|
|
|
else if (_reader.name() == "Name")
|
2016-10-24 00:51:19 +02:00
|
|
|
w.setName(_reader.readElementText());
|
2016-10-23 11:09:20 +02:00
|
|
|
else if (_reader.name() == "Notes")
|
2016-10-24 00:51:19 +02:00
|
|
|
w.setDescription(_reader.readElementText());
|
2016-10-23 11:09:20 +02:00
|
|
|
else if (_reader.name() == "AltitudeMeters")
|
2016-10-24 00:51:19 +02:00
|
|
|
w.setElevation(_reader.readElementText().toDouble());
|
2016-10-23 11:09:20 +02:00
|
|
|
else if (_reader.name() == "Time")
|
2016-10-24 00:51:19 +02:00
|
|
|
w.setTimestamp(QDateTime::fromString(_reader.readElementText(),
|
|
|
|
Qt::ISODate));
|
2016-10-23 11:09:20 +02:00
|
|
|
else
|
|
|
|
_reader.skipCurrentElement();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TCXParser::trackpoints()
|
|
|
|
{
|
|
|
|
while (_reader.readNextStartElement()) {
|
|
|
|
if (_reader.name() == "Trackpoint") {
|
2016-10-24 00:51:19 +02:00
|
|
|
Trackpoint t;
|
|
|
|
trackpointData(t);
|
|
|
|
if (t.coordinates().isValid())
|
|
|
|
_track->append(t);
|
2016-10-23 11:09:20 +02:00
|
|
|
} else
|
|
|
|
_reader.skipCurrentElement();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TCXParser::routepoints()
|
|
|
|
{
|
|
|
|
while (_reader.readNextStartElement()) {
|
|
|
|
if (_reader.name() == "Trackpoint") {
|
2016-10-24 00:51:19 +02:00
|
|
|
Waypoint w;
|
|
|
|
routepointData(w);
|
|
|
|
if (w.coordinates().isValid())
|
|
|
|
_route->append(w);
|
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>());
|
|
|
|
_track = &_tracks.back();
|
|
|
|
trackpoints();
|
|
|
|
} else
|
|
|
|
_reader.skipCurrentElement();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TCXParser::course()
|
|
|
|
{
|
|
|
|
while (_reader.readNextStartElement()) {
|
|
|
|
if (_reader.name() == "Track") {
|
|
|
|
_routes.append(QVector<Waypoint>());
|
|
|
|
_route = &_routes.back();
|
|
|
|
routepoints();
|
|
|
|
} else if (_reader.name() == "CoursePoint") {
|
2016-10-24 00:51:19 +02:00
|
|
|
Waypoint w;
|
|
|
|
waypointData(w);
|
|
|
|
if (w.coordinates().isValid())
|
|
|
|
_waypoints.append(w);
|
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();
|
|
|
|
}
|