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

261 lines
5.1 KiB
C++
Raw Normal View History

#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();
2016-10-25 22:50:11 +02:00
for (cp = sp; cp < ep; cp++)
if (!cp->isSpace())
break;
for (vp = cp; cp <= ep; cp++) {
if (*cp == ',') {
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;
2016-10-25 22:50:11 +02:00
} 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;
}
}
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();
2016-10-25 22:50:11 +02:00
for (cp = sp; cp < ep; cp++)
if (!cp->isSpace())
break;
for (vp = cp; cp <= ep; cp++) {
if (*cp == ',') {
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;
c++;
vp = cp + 1;
2016-10-25 22:50:11 +02:00
} else if (cp->isSpace() || cp->isNull()) {
if (c < 1 || c > 2)
return false;
2016-10-25 22:50:11 +02:00
#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())
cp++;
c = 0;
2016-10-25 22:50:11 +02:00
vp = cp;
}
}
2016-10-25 22:50:11 +02:00
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()
{
while (_reader.readNextStartElement()) {
if (_reader.name() == "coordinates") {
_routes.append(QVector<Waypoint>());
_route = &_routes.back();
if (!lineCoordinates())
_reader.raiseError("Invalid coordinates.");
} else
_reader.skipCurrentElement();
}
}
2016-10-25 22:50:11 +02:00
void KMLParser::point(const QString &name, const QString &desc,
const QDateTime timestamp)
{
while (_reader.readNextStartElement()) {
if (_reader.name() == "coordinates") {
if (!pointCoordinates())
_reader.raiseError("Invalid coordinates.");
2016-10-25 22:50:11 +02:00
else {
Waypoint &w = _waypoints.last();
if (!name.isNull())
w.setName(name);
if (!desc.isNull())
w.setDescription(desc);
if (!timestamp.isNull())
w.setTimestamp(timestamp);
}
} else
_reader.skipCurrentElement();
}
}
2016-10-25 22:50:11 +02:00
void KMLParser::multiGeometry(const QString &name, const QString &desc,
const QDateTime timestamp)
{
while (_reader.readNextStartElement()) {
if (_reader.name() == "Point")
2016-10-25 22:50:11 +02:00
point(name, desc, timestamp);
else if (_reader.name() == "LineString")
lineString();
else
_reader.skipCurrentElement();
}
}
void KMLParser::placemark()
{
2016-10-25 22:50:11 +02:00
QString name, desc;
QDateTime date;
while (_reader.readNextStartElement()) {
2016-10-25 22:50:11 +02:00
if (_reader.name() == "name")
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")
lineString();
else if (_reader.name() == "MultiGeometry")
2016-10-25 22:50:11 +02:00
multiGeometry(name, desc, date);
else
_reader.skipCurrentElement();
}
}
void KMLParser::folder()
{
while (_reader.readNextStartElement()) {
if (_reader.name() == "Placemark")
placemark();
else
_reader.skipCurrentElement();
}
}
void KMLParser::document()
{
while (_reader.readNextStartElement()) {
if (_reader.name() == "Placemark")
placemark();
2016-10-25 22:50:11 +02:00
else if (_reader.name() == "Folder")
folder();
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();
}