Skip to content

Commit c43dfeb

Browse files
author
larsl
committedJun 30, 2005
Keep elevation data and timestamps for trackpoints so it isn't lost when you edit a GPX file
git-svn-id: http://svn.osgeo.org/qgis/branches/Release-0_7-candidate@3677 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent a40051f commit c43dfeb

File tree

2 files changed

+68
-18
lines changed

2 files changed

+68
-18
lines changed
 

‎qgis/providers/gpx/gpsdata.cpp

Lines changed: 60 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <stdexcept>
2020

2121
#include <qfile.h>
22+
#include <qdatetime.h>
2223

2324
#include "gpsdata.h"
2425

@@ -61,6 +62,8 @@ void GPSPoint::writeXML(QTextStream& stream) {
6162
stream<<"<ele>"<<ele<<"</ele>\n";
6263
if (!sym.isEmpty())
6364
stream<<"<sym>"<<xmlify(sym)<<"</sym>\n";
65+
if (time.isValid())
66+
stream<<"<time>"<<time.toString(Qt::ISODate)<<"Z</time>\n";
6467
}
6568

6669

@@ -387,9 +390,9 @@ bool GPXHandler::startElement(const XML_Char* qName, const XML_Char** attr) {
387390
mWpt = Waypoint();
388391
for (int i = 0; attr[2*i] != NULL; ++i) {
389392
if (!std::strcmp(attr[2*i], "lat"))
390-
mWpt.lat = mCLocale.toDouble(attr[2*i+1]);
393+
mWpt.lat = mCLocale.toDouble(attr[2*i+1]);
391394
else if (!std::strcmp(attr[2*i], "lon"))
392-
mWpt.lon = mCLocale.toDouble(attr[2*i+1]);
395+
mWpt.lon = mCLocale.toDouble(attr[2*i+1]);
393396
}
394397
mObj = &mWpt;
395398
}
@@ -407,8 +410,8 @@ bool GPXHandler::startElement(const XML_Char* qName, const XML_Char** attr) {
407410
// common properties
408411
else if (!std::strcmp(qName, "name")) {
409412
if (parseModes.top() == ParsingWaypoint ||
410-
parseModes.top() == ParsingRoute ||
411-
parseModes.top() == ParsingTrack) {
413+
parseModes.top() == ParsingRoute ||
414+
parseModes.top() == ParsingTrack) {
412415
mString = &mObj->name;
413416
mCharBuffer = "";
414417
parseModes.push(ParsingString);
@@ -418,8 +421,8 @@ bool GPXHandler::startElement(const XML_Char* qName, const XML_Char** attr) {
418421
}
419422
else if (!std::strcmp(qName, "cmt")) {
420423
if (parseModes.top() == ParsingWaypoint ||
421-
parseModes.top() == ParsingRoute ||
422-
parseModes.top() == ParsingTrack) {
424+
parseModes.top() == ParsingRoute ||
425+
parseModes.top() == ParsingTrack) {
423426
mString = &mObj->cmt;
424427
mCharBuffer = "";
425428
parseModes.push(ParsingString);
@@ -429,8 +432,8 @@ bool GPXHandler::startElement(const XML_Char* qName, const XML_Char** attr) {
429432
}
430433
else if (!std::strcmp(qName, "desc")) {
431434
if (parseModes.top() == ParsingWaypoint ||
432-
parseModes.top() == ParsingRoute ||
433-
parseModes.top() == ParsingTrack) {
435+
parseModes.top() == ParsingRoute ||
436+
parseModes.top() == ParsingTrack) {
434437
mString = &mObj->desc;
435438
mCharBuffer = "";
436439
parseModes.push(ParsingString);
@@ -440,8 +443,8 @@ bool GPXHandler::startElement(const XML_Char* qName, const XML_Char** attr) {
440443
}
441444
else if (!std::strcmp(qName, "src")) {
442445
if (parseModes.top() == ParsingWaypoint ||
443-
parseModes.top() == ParsingRoute ||
444-
parseModes.top() == ParsingTrack) {
446+
parseModes.top() == ParsingRoute ||
447+
parseModes.top() == ParsingTrack) {
445448
mString = &mObj->src;
446449
mCharBuffer = "";
447450
parseModes.push(ParsingString);
@@ -451,8 +454,8 @@ bool GPXHandler::startElement(const XML_Char* qName, const XML_Char** attr) {
451454
}
452455
else if (!std::strcmp(qName, "url")) {
453456
if (parseModes.top() == ParsingWaypoint ||
454-
parseModes.top() == ParsingRoute ||
455-
parseModes.top() == ParsingTrack) {
457+
parseModes.top() == ParsingRoute ||
458+
parseModes.top() == ParsingTrack) {
456459
mString = &mObj->url;
457460
mCharBuffer = "";
458461
parseModes.push(ParsingString);
@@ -462,8 +465,8 @@ bool GPXHandler::startElement(const XML_Char* qName, const XML_Char** attr) {
462465
}
463466
else if (!std::strcmp(qName, "urlname")) {
464467
if (parseModes.top() == ParsingWaypoint ||
465-
parseModes.top() == ParsingRoute ||
466-
parseModes.top() == ParsingTrack) {
468+
parseModes.top() == ParsingRoute ||
469+
parseModes.top() == ParsingTrack) {
467470
mString = &mObj->urlname;
468471
mCharBuffer = "";
469472
parseModes.push(ParsingString);
@@ -472,16 +475,33 @@ bool GPXHandler::startElement(const XML_Char* qName, const XML_Char** attr) {
472475
parseModes.push(ParsingUnknown);
473476
}
474477

475-
// waypoint-specific attributes
478+
// point-specific attributes
476479
else if (!std::strcmp(qName, "ele")) {
477-
if (parseModes.top() == ParsingWaypoint) {
478-
mDouble = &mWpt.ele;
480+
if (parseModes.top() == ParsingWaypoint ||
481+
parseModes.top() == ParsingTrackpoint) {
482+
if (parseModes.top() == ParsingWaypoint)
483+
mDouble = &mWpt.ele;
484+
else if (parseModes.top() == ParsingTrackpoint)
485+
mDouble = &mTrkpt.ele;
479486
mCharBuffer = "";
480487
parseModes.push(ParsingDouble);
481488
}
482489
else
483490
parseModes.push(ParsingUnknown);
484491
}
492+
else if (!std::strcmp(qName, "time")) {
493+
if (parseModes.top() == ParsingWaypoint ||
494+
parseModes.top() == ParsingTrackpoint) {
495+
if (parseModes.top() == ParsingWaypoint)
496+
mTime = &mWpt.time;
497+
else if (parseModes.top() == ParsingTrackpoint)
498+
mTime = &mTrkpt.time;
499+
mCharBuffer = "";
500+
parseModes.push(ParsingTimestamp);
501+
}
502+
else
503+
parseModes.push(ParsingUnknown);
504+
}
485505
else if (!std::strcmp(qName, "sym")) {
486506
if (parseModes.top() == ParsingWaypoint) {
487507
mString = &mWpt.sym;
@@ -605,8 +625,30 @@ bool GPXHandler::endElement(const std::string& qName) {
605625
*mString = mCharBuffer;
606626
mCharBuffer = "";
607627
}
628+
else if (parseModes.top() == ParsingTimestamp) {
629+
*mTime = QDateTime();
630+
if (mTimezoneRegex.exactMatch(mCharBuffer))
631+
*mTime = QDateTime::fromString(mTimezoneRegex.cap(1), Qt::ISODate);
632+
if (mTime->isValid()) {
633+
QString zone = mTimezoneRegex.cap(2);
634+
if (zone != "Z") {
635+
int sign = (zone[0] == '+' ? 1 : -1);
636+
zone = zone.right(zone.length() - 1);
637+
int n = zone.find(':');
638+
int h = zone.left(n).toInt();
639+
int m = zone.right(zone.length() - n - 1).toInt();
640+
*mTime = mTime->addSecs(sign * (h * 3600 + m * 60));
641+
}
642+
}
643+
else {
644+
std::cerr<<"Found invalid date in GPX file: "<<mCharBuffer<<std::endl;
645+
}
646+
mCharBuffer = "";
647+
}
608648
parseModes.pop();
609649

610650
return true;
611651
}
612-
652+
653+
654+
QRegExp GPXHandler::mTimezoneRegex("(.*)(Z|(?:\\+|-)\\d+:\\d+)");

‎qgis/providers/gpx/gpsdata.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@
2727
#include <vector>
2828

2929
#include <expat.h>
30+
#include <qdatetime.h>
3031
#include <qlocale.h>
32+
#include <qregexp.h>
3133
#include <qstring.h>
3234
#include <qtextstream.h>
3335

@@ -54,6 +56,7 @@ class GPSPoint : public GPSObject {
5456
virtual void writeXML(QTextStream& stream);
5557
double lat, lon, ele;
5658
QString sym;
59+
QDateTime time;
5760
};
5861

5962

@@ -282,6 +285,7 @@ class GPXHandler {
282285
ParsingDouble,
283286
ParsingInt,
284287
ParsingString,
288+
ParsingTimestamp,
285289
ParsingUnknown
286290
};
287291

@@ -297,10 +301,14 @@ class GPXHandler {
297301
Trackpoint mTrkpt;
298302
GPSObject* mObj;
299303
QString* mString;
304+
QDateTime* mTime;
300305
double* mDouble;
301306
int* mInt;
302307
QString mCharBuffer;
303308
QLocale mCLocale;
309+
310+
static QRegExp mTimezoneRegex;
311+
304312
};
305313

306314

0 commit comments

Comments
 (0)
Please sign in to comment.