1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-11-24 11:45:53 +01:00

Added support for KML files

Fixed some minor parser issues
This commit is contained in:
Martin Tůma 2016-10-24 20:00:29 +02:00
parent 1c5a19a33a
commit b99def1b30
2 changed files with 214 additions and 0 deletions

177
src/kmlparser.cpp Normal file
View File

@ -0,0 +1,177 @@
#include "kmlparser.h"
bool KMLParser::pointCoordinates()
{
QString data = _reader.readElementText();
const QChar *sp, *ep, *cp, *vp;
int c = 0;
qreal val[3];
bool res;
sp = data.constData();
ep = sp + data.size();
for (cp = sp, vp = sp; cp <= ep; cp++) {
if (*cp == ',' || cp->isNull()) {
if (c > 2)
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;
if (c == 2) {
Waypoint w(Coordinates(val[0], val[1]));
w.setElevation(val[2]);
_waypoints.append(w);
}
c++;
vp = cp + 1;
}
}
return true;
}
bool KMLParser::lineCoordinates()
{
QString data = _reader.readElementText();
const QChar *sp, *ep, *cp, *vp;
int c = 0;
qreal val[3];
bool res;
sp = data.constData();
ep = sp + data.size();
for (cp = sp, vp = sp; cp <= ep; cp++) {
if (*cp == ',' || cp->isSpace() || cp->isNull()) {
if (c > 2)
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;
if (c == 2) {
Waypoint w(Coordinates(val[0], val[1]));
w.setElevation(val[2]);
_route->append(w);
}
c++;
vp = cp + 1;
}
if (cp->isSpace()) {
if (c < 3)
return false;
while (cp->isSpace())
cp++;
c = 0;
}
}
return true;
}
void KMLParser::lineString()
{
while (_reader.readNextStartElement()) {
if (_reader.name() == "coordinates") {
_routes.append(QVector<Waypoint>());
_route = &_routes.back();
if (!lineCoordinates())
_reader.raiseError("Invalid coordinates.");
} else
_reader.skipCurrentElement();
}
}
void KMLParser::point()
{
while (_reader.readNextStartElement()) {
if (_reader.name() == "coordinates") {
if (!pointCoordinates())
_reader.raiseError("Invalid coordinates.");
} else
_reader.skipCurrentElement();
}
}
void KMLParser::multiGeometry()
{
while (_reader.readNextStartElement()) {
if (_reader.name() == "Point")
point();
else if (_reader.name() == "LineString")
lineString();
else
_reader.skipCurrentElement();
}
}
void KMLParser::placemark()
{
while (_reader.readNextStartElement()) {
if (_reader.name() == "Point")
point();
else if (_reader.name() == "LineString")
lineString();
else if (_reader.name() == "MultiGeometry")
multiGeometry();
else
_reader.skipCurrentElement();
}
}
void KMLParser::document()
{
while (_reader.readNextStartElement()) {
if (_reader.name() == "Placemark")
placemark();
else
_reader.skipCurrentElement();
}
}
void KMLParser::kml()
{
while (_reader.readNextStartElement()) {
if (_reader.name() == "Document")
document();
else
_reader.skipCurrentElement();
}
}
bool KMLParser::parse()
{
if (_reader.readNextStartElement()) {
if (_reader.name() == "kml")
kml();
else
_reader.raiseError("Not a KML file.");
}
return !_reader.error();
}
bool KMLParser::loadFile(QIODevice *device)
{
_reader.clear();
_reader.setDevice(device);
return parse();
}

37
src/kmlparser.h Normal file
View File

@ -0,0 +1,37 @@
#ifndef KMLPARSER_H
#define KMLPARSER_H
#include <QXmlStreamReader>
#include <QVector>
#include "parser.h"
class KMLParser : public Parser
{
public:
KMLParser(QList<QVector<Trackpoint> > &tracks,
QList<QVector<Waypoint> > &routes, QList<Waypoint> &waypoints)
: Parser(tracks, routes, waypoints) {_track = 0; _route = 0;}
~KMLParser() {}
bool loadFile(QIODevice *device);
QString errorString() const {return _reader.errorString();}
int errorLine() const {return _reader.lineNumber();}
const char *name() const {return "KML";}
private:
bool parse();
void kml();
void document();
void placemark();
void multiGeometry();
void lineString();
void point();
bool pointCoordinates();
bool lineCoordinates();
QXmlStreamReader _reader;
QVector<Trackpoint> *_track;
QVector<Waypoint> *_route;
};
#endif // KMLPARSER_H