1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-11-30 22:51:16 +01:00

Improved KML parser

This commit is contained in:
Martin Tůma 2016-10-25 22:50:11 +02:00
parent 6cc22afcdc
commit 721ee2aaa9
2 changed files with 110 additions and 22 deletions

View File

@ -13,8 +13,12 @@ bool KMLParser::pointCoordinates()
sp = data.constData(); sp = data.constData();
ep = sp + data.size(); ep = sp + data.size();
for (cp = sp, vp = sp; cp <= ep; cp++) { for (cp = sp; cp < ep; cp++)
if (*cp == ',' || cp->isNull()) { if (!cp->isSpace())
break;
for (vp = cp; cp <= ep; cp++) {
if (*cp == ',') {
if (c > 2) if (c > 2)
return false; return false;
@ -34,6 +38,26 @@ bool KMLParser::pointCoordinates()
c++; c++;
vp = cp + 1; vp = cp + 1;
} else if (cp->isSpace() || cp->isNull()) {
if (c < 1)
return false;
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
val[c] = QString(vp, cp - vp).toDouble(&res);
#else // QT_VERSION < 5
val[c] = QStringRef(&data, vp - sp, cp - vp).toDouble(&res);
#endif // QT_VERSION < 5
if (!res)
return false;
Waypoint w(Coordinates(val[0], val[1]));
if (c == 2)
w.setElevation(val[2]);
_waypoints.append(w);
while (cp->isSpace())
cp++;
c = 3;
} }
} }
@ -52,8 +76,12 @@ bool KMLParser::lineCoordinates()
sp = data.constData(); sp = data.constData();
ep = sp + data.size(); ep = sp + data.size();
for (cp = sp, vp = sp; cp <= ep; cp++) { for (cp = sp; cp < ep; cp++)
if (*cp == ',' || cp->isSpace() || cp->isNull()) { if (!cp->isSpace())
break;
for (vp = cp; cp <= ep; cp++) {
if (*cp == ',') {
if (c > 2) if (c > 2)
return false; return false;
@ -65,25 +93,48 @@ bool KMLParser::lineCoordinates()
if (!res) if (!res)
return false; return false;
if (c == 2) {
Waypoint w(Coordinates(val[0], val[1]));
w.setElevation(val[2]);
_route->append(w);
}
c++; c++;
vp = cp + 1; vp = cp + 1;
} } else if (cp->isSpace() || cp->isNull()) {
if (cp->isSpace()) { if (c < 1 || c > 2)
if (c < 3)
return false; return false;
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
val[c] = QString(vp, cp - vp).toDouble(&res);
#else // QT_VERSION < 5
val[c] = QStringRef(&data, vp - sp, cp - vp).toDouble(&res);
#endif // QT_VERSION < 5
if (!res)
return false;
Waypoint w(Coordinates(val[0], val[1]));
if (c == 2)
w.setElevation(val[2]);
_route->append(w);
while (cp->isSpace()) while (cp->isSpace())
cp++; cp++;
c = 0; c = 0;
vp = cp;
} }
} }
return true; return true;
}
QDateTime KMLParser::timeStamp()
{
QDateTime date;
while (_reader.readNextStartElement()) {
if (_reader.name() == "when") {
date = QDateTime::fromString(_reader.readElementText(),
Qt::ISODate);
} else
_reader.skipCurrentElement();
}
return date;
} }
void KMLParser::lineString() void KMLParser::lineString()
@ -99,22 +150,33 @@ void KMLParser::lineString()
} }
} }
void KMLParser::point() void KMLParser::point(const QString &name, const QString &desc,
const QDateTime timestamp)
{ {
while (_reader.readNextStartElement()) { while (_reader.readNextStartElement()) {
if (_reader.name() == "coordinates") { if (_reader.name() == "coordinates") {
if (!pointCoordinates()) if (!pointCoordinates())
_reader.raiseError("Invalid coordinates."); _reader.raiseError("Invalid coordinates.");
else {
Waypoint &w = _waypoints.last();
if (!name.isNull())
w.setName(name);
if (!desc.isNull())
w.setDescription(desc);
if (!timestamp.isNull())
w.setTimestamp(timestamp);
}
} else } else
_reader.skipCurrentElement(); _reader.skipCurrentElement();
} }
} }
void KMLParser::multiGeometry() void KMLParser::multiGeometry(const QString &name, const QString &desc,
const QDateTime timestamp)
{ {
while (_reader.readNextStartElement()) { while (_reader.readNextStartElement()) {
if (_reader.name() == "Point") if (_reader.name() == "Point")
point(); point(name, desc, timestamp);
else if (_reader.name() == "LineString") else if (_reader.name() == "LineString")
lineString(); lineString();
else else
@ -124,13 +186,32 @@ void KMLParser::multiGeometry()
void KMLParser::placemark() void KMLParser::placemark()
{ {
QString name, desc;
QDateTime date;
while (_reader.readNextStartElement()) { while (_reader.readNextStartElement()) {
if (_reader.name() == "Point") if (_reader.name() == "name")
point(); name = _reader.readElementText();
else if (_reader.name() == "description")
desc = _reader.readElementText();
else if (_reader.name() == "TimeStamp")
date = timeStamp();
else if (_reader.name() == "Point")
point(name, desc, date);
else if (_reader.name() == "LineString") else if (_reader.name() == "LineString")
lineString(); lineString();
else if (_reader.name() == "MultiGeometry") else if (_reader.name() == "MultiGeometry")
multiGeometry(); multiGeometry(name, desc, date);
else
_reader.skipCurrentElement();
}
}
void KMLParser::folder()
{
while (_reader.readNextStartElement()) {
if (_reader.name() == "Placemark")
placemark();
else else
_reader.skipCurrentElement(); _reader.skipCurrentElement();
} }
@ -141,6 +222,8 @@ void KMLParser::document()
while (_reader.readNextStartElement()) { while (_reader.readNextStartElement()) {
if (_reader.name() == "Placemark") if (_reader.name() == "Placemark")
placemark(); placemark();
else if (_reader.name() == "Folder")
folder();
else else
_reader.skipCurrentElement(); _reader.skipCurrentElement();
} }

View File

@ -3,6 +3,7 @@
#include <QXmlStreamReader> #include <QXmlStreamReader>
#include <QVector> #include <QVector>
#include <QDateTime>
#include "parser.h" #include "parser.h"
class KMLParser : public Parser class KMLParser : public Parser
@ -22,12 +23,16 @@ private:
bool parse(); bool parse();
void kml(); void kml();
void document(); void document();
void folder();
void placemark(); void placemark();
void multiGeometry(); void multiGeometry(const QString &name, const QString &desc,
const QDateTime timestamp);
void lineString(); void lineString();
void point(); void point(const QString &name, const QString &desc,
const QDateTime timestamp);
bool pointCoordinates(); bool pointCoordinates();
bool lineCoordinates(); bool lineCoordinates();
QDateTime timeStamp();
QXmlStreamReader _reader; QXmlStreamReader _reader;
QVector<Trackpoint> *_track; QVector<Trackpoint> *_track;