1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-10-07 07:13:21 +02:00
GPXSee/src/gpxparser.cpp

240 lines
5.2 KiB
C++
Raw Normal View History

2016-10-23 11:09:20 +02:00
#include "gpxparser.h"
2015-10-05 01:43:48 +02:00
qreal GPXParser::number()
{
bool res;
qreal ret = _reader.readElementText().toDouble(&res);
if (!res)
_reader.raiseError(QString("Invalid %1.").arg(
_reader.name().toString()));
2015-10-05 01:43:48 +02:00
return ret;
}
QDateTime GPXParser::time()
2016-08-09 01:16:19 +02:00
{
QDateTime d = QDateTime::fromString(_reader.readElementText(),
Qt::ISODate);
if (!d.isValid())
_reader.raiseError(QString("Invalid %1.").arg(
_reader.name().toString()));
return d;
2016-08-09 01:16:19 +02:00
}
Coordinates GPXParser::coordinates()
{
bool res;
qreal lon, lat;
const QXmlStreamAttributes &attr = _reader.attributes();
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
lon = attr.value("lon").toString().toDouble(&res);
#else // QT_VERSION < 5
lon = attr.value("lon").toDouble(&res);
#endif // QT_VERSION < 5
if (!res || (lon < -180.0 || lon > 180.0)) {
_reader.raiseError("Invalid longitude.");
return Coordinates();
}
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
lat = attr.value("lat").toString().toDouble(&res);
#else // QT_VERSION < 5
lat = attr.value("lat").toDouble(&res);
#endif // QT_VERSION < 5
if (!res || (lat < -90.0 || lat > 90.0)) {
_reader.raiseError("Invalid latitude.");
return Coordinates();
}
return Coordinates(lon, lat);
}
void GPXParser::handleTrackpointData(DataType type)
2016-08-09 01:16:19 +02:00
{
switch (type) {
case Elevation:
_track->last().setElevation(number());
break;
case Time:
_track->last().setTimestamp(time());
break;
case Speed:
_track->last().setSpeed(number());
break;
case HeartRate:
_track->last().setHeartRate(number());
break;
case Temperature:
_track->last().setTemperature(number());
break;
default:
break;
}
2016-08-09 01:16:19 +02:00
}
void GPXParser::handleWaypointData(DataType type, Waypoint &waypoint)
{
switch (type) {
case Name:
waypoint.setName(_reader.readElementText());
break;
case Description:
waypoint.setDescription(_reader.readElementText());
break;
case Time:
waypoint.setTimestamp(time());
break;
case Elevation:
waypoint.setElevation(number());
break;
default:
break;
}
}
2015-10-05 01:43:48 +02:00
2016-10-23 11:09:20 +02:00
void GPXParser::tpExtension()
{
while (_reader.readNextStartElement()) {
2016-06-20 23:56:42 +02:00
if (_reader.name() == "hr")
handleTrackpointData(HeartRate);
2016-06-20 23:56:42 +02:00
else if (_reader.name() == "atemp")
handleTrackpointData(Temperature);
else
_reader.skipCurrentElement();
}
}
2016-10-23 11:09:20 +02:00
void GPXParser::extensions()
{
while (_reader.readNextStartElement()) {
2016-06-20 23:56:42 +02:00
if (_reader.name() == "speed")
handleTrackpointData(Speed);
2016-06-20 23:56:42 +02:00
else if (_reader.name() == "hr" || _reader.name() == "heartrate")
handleTrackpointData(HeartRate);
2016-06-20 23:56:42 +02:00
else if (_reader.name() == "temp")
handleTrackpointData(Temperature);
else if (_reader.name() == "TrackPointExtension")
tpExtension();
else
_reader.skipCurrentElement();
}
}
2016-10-23 11:09:20 +02:00
void GPXParser::trackpointData()
2015-10-05 01:43:48 +02:00
{
qreal gh = NAN;
2015-10-05 01:43:48 +02:00
while (_reader.readNextStartElement()) {
2016-06-20 23:56:42 +02:00
if (_reader.name() == "ele")
handleTrackpointData(Elevation);
2016-06-20 23:56:42 +02:00
else if (_reader.name() == "time")
handleTrackpointData(Time);
2016-06-20 23:56:42 +02:00
else if (_reader.name() == "geoidheight")
gh = number();
else if (_reader.name() == "extensions")
extensions();
2015-10-05 01:43:48 +02:00
else
_reader.skipCurrentElement();
}
Trackpoint &t = _track->last();
if (!std::isnan(gh) && !std::isnan(t.elevation()))
t.setElevation(t.elevation() - gh);
2016-08-09 01:16:19 +02:00
}
void GPXParser::waypointData(Waypoint &waypoint)
2016-10-23 11:09:20 +02:00
{
qreal gh = NAN;
2016-10-23 11:09:20 +02:00
while (_reader.readNextStartElement()) {
if (_reader.name() == "name")
handleWaypointData(Name, waypoint);
2016-10-23 11:09:20 +02:00
else if (_reader.name() == "desc")
handleWaypointData(Description, waypoint);
2016-10-23 11:09:20 +02:00
else if (_reader.name() == "ele")
handleWaypointData(Elevation, waypoint);
2016-10-23 11:09:20 +02:00
else if (_reader.name() == "geoidheight")
gh = number();
2016-10-23 11:09:20 +02:00
else if (_reader.name() == "time")
handleWaypointData(Time, waypoint);
2016-10-23 11:09:20 +02:00
else
_reader.skipCurrentElement();
}
if (!std::isnan(gh) && !std::isnan(waypoint.elevation()))
waypoint.setElevation(waypoint.elevation() - gh);
2016-10-23 11:09:20 +02:00
}
void GPXParser::trackpoints()
2015-10-05 01:43:48 +02:00
{
while (_reader.readNextStartElement()) {
if (_reader.name() == "trkpt") {
_track->append(Trackpoint(coordinates()));
2016-06-21 00:12:34 +02:00
trackpointData();
2015-10-05 01:43:48 +02:00
} else
_reader.skipCurrentElement();
}
}
2016-10-23 11:09:20 +02:00
void GPXParser::routepoints()
2016-08-09 01:16:19 +02:00
{
while (_reader.readNextStartElement()) {
if (_reader.name() == "rtept") {
_route->append(Waypoint(coordinates()));
waypointData(_route->last());
2016-08-09 01:16:19 +02:00
} else
_reader.skipCurrentElement();
}
}
2016-10-23 11:09:20 +02:00
void GPXParser::track()
2015-10-05 01:43:48 +02:00
{
while (_reader.readNextStartElement()) {
if (_reader.name() == "trkseg") {
2016-06-21 00:12:34 +02:00
trackpoints();
2015-10-05 01:43:48 +02:00
} else
_reader.skipCurrentElement();
}
}
2016-10-23 11:09:20 +02:00
void GPXParser::gpx()
2015-10-05 01:43:48 +02:00
{
while (_reader.readNextStartElement()) {
if (_reader.name() == "trk") {
2016-02-19 21:42:54 +01:00
_tracks.append(QVector<Trackpoint>());
_track = &_tracks.back();
track();
2016-08-09 01:16:19 +02:00
} else if (_reader.name() == "rte") {
_routes.append(QVector<Waypoint>());
_route = &_routes.back();
routepoints();
} else if (_reader.name() == "wpt") {
_waypoints.append(Waypoint(coordinates()));
waypointData(_waypoints.last());
} else
2015-10-05 01:43:48 +02:00
_reader.skipCurrentElement();
}
}
2016-10-23 11:09:20 +02:00
bool GPXParser::parse()
2015-10-05 01:43:48 +02:00
{
if (_reader.readNextStartElement()) {
if (_reader.name() == "gpx")
gpx();
2015-10-05 01:43:48 +02:00
else
_reader.raiseError("Not a GPX file.");
2015-10-05 01:43:48 +02:00
}
return !_reader.error();
}
2016-10-23 11:09:20 +02:00
bool GPXParser::loadFile(QIODevice *device)
2015-10-05 01:43:48 +02:00
{
_reader.clear();
_reader.setDevice(device);
return parse();
2015-10-05 01:43:48 +02:00
}