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

248 lines
4.9 KiB
C++
Raw Normal View History

#include "kmlparser.h"
2016-10-27 22:33:35 +02:00
qreal KMLParser::number()
{
bool res;
qreal ret = _reader.readElementText().toDouble(&res);
if (!res)
_reader.raiseError(QString("Invalid %1.").arg(
_reader.name().toString()));
return ret;
}
QDateTime KMLParser::time()
{
QDateTime d = QDateTime::fromString(_reader.readElementText(),
Qt::ISODate);
if (!d.isValid())
_reader.raiseError(QString("Invalid %1.").arg(
_reader.name().toString()));
return d;
}
bool KMLParser::pointCoordinates(Waypoint &waypoint)
{
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)
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;
2016-10-27 22:33:35 +02:00
waypoint.setCoordinates(Coordinates(val[0], val[1]));
2016-10-25 22:50:11 +02:00
if (c == 2)
2016-10-27 22:33:35 +02:00
waypoint.setElevation(val[2]);
2016-10-25 22:50:11 +02:00
while (cp->isSpace())
cp++;
c = 3;
}
}
return true;
}
2016-10-27 22:33:35 +02:00
bool KMLParser::lineCoordinates(QVector<Waypoint> &route)
{
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;
2016-10-27 22:33:35 +02:00
route.append(Waypoint(Coordinates(val[0], val[1])));
2016-10-25 22:50:11 +02:00
if (c == 2)
2016-10-27 22:33:35 +02:00
route.last().setElevation(val[2]);
2016-10-25 22:50:11 +02:00
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;
}
2016-10-27 22:33:35 +02:00
void KMLParser::timeStamp(Waypoint &waypoint)
2016-10-25 22:50:11 +02:00
{
while (_reader.readNextStartElement()) {
2016-10-27 22:33:35 +02:00
if (_reader.name() == "when")
waypoint.setTimestamp(time());
else
2016-10-25 22:50:11 +02:00
_reader.skipCurrentElement();
}
}
2016-10-27 22:33:35 +02:00
void KMLParser::lineString(QVector<Waypoint> &route)
{
while (_reader.readNextStartElement()) {
if (_reader.name() == "coordinates") {
2016-10-27 22:33:35 +02:00
if (!lineCoordinates(route))
_reader.raiseError("Invalid coordinates.");
} else
_reader.skipCurrentElement();
}
}
2016-10-27 22:33:35 +02:00
void KMLParser::point(Waypoint &waypoint)
{
while (_reader.readNextStartElement()) {
if (_reader.name() == "coordinates") {
2016-10-27 22:33:35 +02:00
if (!pointCoordinates(waypoint))
_reader.raiseError("Invalid coordinates.");
} else
_reader.skipCurrentElement();
}
}
void KMLParser::placemark()
{
2016-10-27 22:33:35 +02:00
Waypoint waypoint;
2016-10-25 22:50:11 +02:00
while (_reader.readNextStartElement()) {
2016-10-25 22:50:11 +02:00
if (_reader.name() == "name")
2016-10-27 22:33:35 +02:00
waypoint.setName(_reader.readElementText());
2016-10-25 22:50:11 +02:00
else if (_reader.name() == "description")
2016-10-27 22:33:35 +02:00
waypoint.setDescription(_reader.readElementText());
2016-10-25 22:50:11 +02:00
else if (_reader.name() == "TimeStamp")
2016-10-27 22:33:35 +02:00
timeStamp(waypoint);
else if (_reader.name() == "Point") {
_waypoints.append(waypoint);
point(_waypoints.last());
} else if (_reader.name() == "LineString") {
_routes.append(QVector<Waypoint>());
lineString(_routes.back());
} else
2016-10-25 22:50:11 +02:00
_reader.skipCurrentElement();
}
}
void KMLParser::folder()
{
while (_reader.readNextStartElement()) {
if (_reader.name() == "Placemark")
placemark();
2016-10-26 08:23:18 +02:00
else if (_reader.name() == "Folder")
folder();
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 if (_reader.name() == "Placemark")
placemark();
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();
}