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

720 lines
17 KiB
C++
Raw Normal View History

/*
WARNING: This code uses internal Qt API - the QZipReader class for reading
ZIP files - and things may break if Qt changes the API. For Qt5 this is not
a problem as we can "see the future" now and there are no changes in all
the supported Qt5 versions up to the last one (5.15). In Qt6 the class
might change or even disappear in the future, but this is very unlikely
as there were no changes for several years and The Qt Company's policy
is: "do not invest any resources into any desktop related stuff unless
absolutely necessary". There is an issue (QTBUG-3897) since the year 2009 to
include the ZIP reader into the public API, which aptly illustrates the
effort The Qt Company is willing to make about anything desktop related...
*/
#include <QFileInfo>
#include <QDir>
#include <QTemporaryDir>
#include <private/qzipreader_p.h>
#include "kmlparser.h"
#define ZIP_MAGIC 0x04034b50
static inline uint readUInt(const uchar *data)
{
return (data[0]) + (data[1]<<8) + (data[2]<<16) + (data[3]<<24);
}
2016-10-27 22:33:35 +02:00
qreal KMLParser::number()
{
bool res;
qreal ret = _reader.readElementText().toDouble(&res);
if (!res)
2016-10-29 12:22:28 +02:00
_reader.raiseError(QString("Invalid %1").arg(
2016-10-27 22:33:35 +02:00
_reader.name().toString()));
return ret;
}
QDateTime KMLParser::time()
{
QDateTime d = QDateTime::fromString(_reader.readElementText(),
Qt::ISODate);
if (!d.isValid())
2016-10-29 12:22:28 +02:00
_reader.raiseError(QString("Invalid %1").arg(
2016-10-27 22:33:35 +02:00
_reader.name().toString()));
return d;
}
2016-10-28 19:12:40 +02:00
bool KMLParser::coord(Trackpoint &trackpoint)
{
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; cp < ep; cp++)
if (!cp->isSpace())
break;
for (vp = cp; cp <= ep; cp++) {
if (cp->isSpace() || cp->isNull()) {
if (c > 2)
return false;
val[c] = QString(vp, cp - vp).toDouble(&res);
if (!res)
return false;
if (c == 1) {
trackpoint.setCoordinates(Coordinates(val[0], val[1]));
if (!trackpoint.coordinates().isValid())
return false;
} else if (c == 2)
trackpoint.setElevation(val[2]);
while (cp->isSpace())
cp++;
vp = cp;
c++;
}
}
return true;
}
2016-10-27 22:33:35 +02:00
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 == ',') {
2016-11-11 22:04:26 +01:00
if (c > 1)
return false;
val[c] = QString(vp, cp - vp).toDouble(&res);
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;
val[c] = QString(vp, cp - vp).toDouble(&res);
if (!res)
return false;
2016-10-27 22:33:35 +02:00
waypoint.setCoordinates(Coordinates(val[0], val[1]));
2016-10-28 19:12:40 +02:00
if (!waypoint.coordinates().isValid())
return false;
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;
}
2019-02-11 23:28:08 +01:00
bool KMLParser::lineCoordinates(SegmentData &segment)
{
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 == ',') {
2016-11-11 22:04:26 +01:00
if (c > 1)
return false;
val[c] = QString(vp, cp - vp).toDouble(&res);
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
val[c] = QString(vp, cp - vp).toDouble(&res);
if (!res)
return false;
2019-02-11 23:28:08 +01:00
segment.append(Trackpoint(Coordinates(val[0], val[1])));
if (!segment.last().coordinates().isValid())
2016-10-28 19:12:40 +02:00
return false;
2016-10-25 22:50:11 +02:00
if (c == 2)
2019-02-11 23:28:08 +01:00
segment.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;
}
2019-01-31 01:46:53 +01:00
bool KMLParser::polygonCoordinates(QVector<Coordinates> &points)
{
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; cp < ep; cp++)
if (!cp->isSpace())
break;
for (vp = cp; cp <= ep; cp++) {
if (*cp == ',') {
if (c > 1)
return false;
val[c] = QString(vp, cp - vp).toDouble(&res);
if (!res)
return false;
c++;
vp = cp + 1;
} else if (cp->isSpace() || cp->isNull()) {
if (c < 1 || c > 2)
return false;
val[c] = QString(vp, cp - vp).toDouble(&res);
if (!res)
return false;
points.append(Coordinates(val[0], val[1]));
if (!points.last().isValid())
return false;
while (cp->isSpace())
cp++;
c = 0;
vp = cp;
}
}
return true;
}
QDateTime KMLParser::timeStamp()
2016-10-25 22:50:11 +02:00
{
QDateTime ts;
2016-10-25 22:50:11 +02:00
while (_reader.readNextStartElement()) {
2018-08-27 22:25:55 +02:00
if (_reader.name() == QLatin1String("when"))
ts = time();
2016-10-27 22:33:35 +02:00
else
2016-10-25 22:50:11 +02:00
_reader.skipCurrentElement();
}
return ts;
}
2019-02-11 23:28:08 +01:00
void KMLParser::lineString(SegmentData &segment)
{
while (_reader.readNextStartElement()) {
2018-08-27 22:25:55 +02:00
if (_reader.name() == QLatin1String("coordinates")) {
2019-02-11 23:28:08 +01:00
if (!lineCoordinates(segment))
2016-10-29 12:22:28 +02:00
_reader.raiseError("Invalid coordinates");
} else
_reader.skipCurrentElement();
}
}
2019-01-31 01:46:53 +01:00
void KMLParser::linearRing(QVector<Coordinates> &coordinates)
{
while (_reader.readNextStartElement()) {
if (_reader.name() == QLatin1String("coordinates")) {
if (!polygonCoordinates(coordinates))
_reader.raiseError("Invalid coordinates");
} else
_reader.skipCurrentElement();
}
}
void KMLParser::boundary(QVector<Coordinates> &coordinates)
{
while (_reader.readNextStartElement()) {
if (_reader.name() == QLatin1String("LinearRing"))
linearRing(coordinates);
else
_reader.skipCurrentElement();
}
}
void KMLParser::polygon(Area &area)
{
Polygon polygon;
2019-01-31 01:46:53 +01:00
while (_reader.readNextStartElement()) {
2021-04-10 15:27:40 +02:00
QVector<Coordinates> path;
2019-01-31 01:46:53 +01:00
if (_reader.name() == QLatin1String("outerBoundaryIs")) {
2019-02-01 00:25:41 +01:00
if (!polygon.isEmpty()) {
2019-01-31 01:46:53 +01:00
_reader.raiseError("Multiple polygon outerBoundaryIss");
return;
}
2021-04-10 15:27:40 +02:00
boundary(path);
polygon.append(path);
2019-01-31 01:46:53 +01:00
} else if (_reader.name() == QLatin1String("innerBoundaryIs")) {
2019-02-01 00:25:41 +01:00
if (polygon.isEmpty()) {
2019-01-31 01:46:53 +01:00
_reader.raiseError("Missing polygon outerBoundaryIs");
return;
}
2021-04-10 15:27:40 +02:00
boundary(path);
polygon.append(path);
2019-01-31 01:46:53 +01:00
} else
_reader.skipCurrentElement();
}
area.append(polygon);
2019-01-31 01:46:53 +01:00
}
2016-10-27 22:33:35 +02:00
void KMLParser::point(Waypoint &waypoint)
{
while (_reader.readNextStartElement()) {
2018-08-27 22:25:55 +02:00
if (_reader.name() == QLatin1String("coordinates")) {
2016-10-27 22:33:35 +02:00
if (!pointCoordinates(waypoint))
2016-10-29 12:22:28 +02:00
_reader.raiseError("Invalid coordinates");
} else
_reader.skipCurrentElement();
}
2016-10-29 10:40:30 +02:00
if (waypoint.coordinates().isNull())
2016-10-29 12:22:28 +02:00
_reader.raiseError("Missing Point coordinates");
}
2019-02-11 23:28:08 +01:00
void KMLParser::heartRate(SegmentData &segment, int start)
{
int i = start;
const char error[] = "Heartrate data count mismatch";
while (_reader.readNextStartElement()) {
2018-08-27 22:25:55 +02:00
if (_reader.name() == QLatin1String("value")) {
2019-02-11 23:28:08 +01:00
if (i < segment.size())
segment[i++].setHeartRate(number());
else {
_reader.raiseError(error);
return;
}
} else
_reader.skipCurrentElement();
}
2019-02-11 23:28:08 +01:00
if (i != segment.size())
_reader.raiseError(error);
}
2019-02-11 23:28:08 +01:00
void KMLParser::cadence(SegmentData &segment, int start)
{
int i = start;
const char error[] = "Cadence data count mismatch";
while (_reader.readNextStartElement()) {
2018-08-27 22:25:55 +02:00
if (_reader.name() == QLatin1String("value")) {
2019-02-11 23:28:08 +01:00
if (i < segment.size())
segment[i++].setCadence(number());
else {
_reader.raiseError(error);
return;
}
} else
_reader.skipCurrentElement();
}
2019-02-11 23:28:08 +01:00
if (i != segment.size())
_reader.raiseError(error);
}
2019-02-11 23:28:08 +01:00
void KMLParser::speed(SegmentData &segment, int start)
{
int i = start;
const char error[] = "Speed data count mismatch";
while (_reader.readNextStartElement()) {
2018-08-27 22:25:55 +02:00
if (_reader.name() == QLatin1String("value")) {
2019-02-11 23:28:08 +01:00
if (i < segment.size())
segment[i++].setSpeed(number());
else {
_reader.raiseError(error);
return;
}
} else
_reader.skipCurrentElement();
}
2019-02-11 23:28:08 +01:00
if (i != segment.size())
_reader.raiseError(error);
}
2019-02-11 23:28:08 +01:00
void KMLParser::temperature(SegmentData &segment, int start)
{
int i = start;
const char error[] = "Temperature data count mismatch";
while (_reader.readNextStartElement()) {
2018-08-27 22:25:55 +02:00
if (_reader.name() == QLatin1String("value")) {
2019-02-11 23:28:08 +01:00
if (i < segment.size())
segment[i++].setTemperature(number());
else {
_reader.raiseError(error);
return;
}
} else
_reader.skipCurrentElement();
}
2019-02-11 23:28:08 +01:00
if (i != segment.size())
_reader.raiseError(error);
}
2019-02-11 23:28:08 +01:00
void KMLParser::schemaData(SegmentData &segment, int start)
{
while (_reader.readNextStartElement()) {
2018-08-27 22:25:55 +02:00
if (_reader.name() == QLatin1String("SimpleArrayData")) {
QXmlStreamAttributes attr = _reader.attributes();
QString name(attr.value("name").toString());
2018-08-27 22:25:55 +02:00
if (name == QLatin1String("Heartrate"))
2019-02-11 23:28:08 +01:00
heartRate(segment, start);
2018-08-27 22:25:55 +02:00
else if (name == QLatin1String("Cadence"))
2019-02-11 23:28:08 +01:00
cadence(segment, start);
2018-08-27 22:25:55 +02:00
else if (name == QLatin1String("Speed"))
2019-02-11 23:28:08 +01:00
speed(segment, start);
2018-08-27 22:25:55 +02:00
else if (name == QLatin1String("Temperature"))
2019-02-11 23:28:08 +01:00
temperature(segment, start);
else
_reader.skipCurrentElement();
} else
_reader.skipCurrentElement();
}
}
2019-02-11 23:28:08 +01:00
void KMLParser::extendedData(SegmentData &segment, int start)
{
while (_reader.readNextStartElement()) {
2018-08-27 22:25:55 +02:00
if (_reader.name() == QLatin1String("SchemaData"))
2019-02-11 23:28:08 +01:00
schemaData(segment, start);
else
_reader.skipCurrentElement();
}
}
2019-02-11 23:28:08 +01:00
void KMLParser::track(SegmentData &segment)
2016-10-28 19:12:40 +02:00
{
const char error[] = "gx:coord/when element count mismatch";
2019-02-11 23:28:08 +01:00
int first = segment.size();
int i = first;
2016-10-28 19:12:40 +02:00
while (_reader.readNextStartElement()) {
2018-08-27 22:25:55 +02:00
if (_reader.name() == QLatin1String("when")) {
2019-02-11 23:28:08 +01:00
segment.append(Trackpoint());
segment.last().setTimestamp(time());
2018-08-27 22:25:55 +02:00
} else if (_reader.name() == QLatin1String("coord")) {
2019-02-11 23:28:08 +01:00
if (i == segment.size()) {
_reader.raiseError(error);
2016-10-28 19:12:40 +02:00
return;
2019-02-11 23:28:08 +01:00
} else if (!coord(segment[i])) {
2016-10-29 12:22:28 +02:00
_reader.raiseError("Invalid coordinates");
2016-10-28 19:12:40 +02:00
return;
}
i++;
2018-08-27 22:25:55 +02:00
} else if (_reader.name() == QLatin1String("ExtendedData"))
2019-02-11 23:28:08 +01:00
extendedData(segment, first);
else
2016-10-28 19:12:40 +02:00
_reader.skipCurrentElement();
}
2019-02-11 23:28:08 +01:00
if (i != segment.size())
_reader.raiseError(error);
2016-10-28 19:12:40 +02:00
}
void KMLParser::multiTrack(TrackData &t)
{
while (_reader.readNextStartElement()) {
2019-02-11 23:28:08 +01:00
if (_reader.name() == QLatin1String("Track")) {
t.append(SegmentData());
track(t.last());
} else
_reader.skipCurrentElement();
}
}
2019-01-31 01:46:53 +01:00
void KMLParser::multiGeometry(QList<TrackData> &tracks, QList<Area> &areas,
2019-01-18 00:17:28 +01:00
QVector<Waypoint> &waypoints, const QString &name, const QString &desc,
2019-03-05 22:52:14 +01:00
const QDateTime &timestamp)
{
while (_reader.readNextStartElement()) {
2018-08-27 22:25:55 +02:00
if (_reader.name() == QLatin1String("Point")) {
2017-07-27 19:47:46 +02:00
waypoints.append(Waypoint());
Waypoint &w = waypoints.last();
w.setName(name);
w.setDescription(desc);
w.setTimestamp(timestamp);
point(w);
2018-08-27 22:25:55 +02:00
} else if (_reader.name() == QLatin1String("LineString")) {
2017-07-27 19:47:46 +02:00
tracks.append(TrackData());
TrackData &t = tracks.last();
2019-02-11 23:28:08 +01:00
t.append(SegmentData());
t.setName(name);
t.setDescription(desc);
2019-02-11 23:28:08 +01:00
lineString(t.last());
2019-01-31 01:46:53 +01:00
} else if (_reader.name() == QLatin1String("Polygon")) {
areas.append(Area());
Area &a = areas.last();
a.setName(name);
a.setDescription(desc);
polygon(a);
} else
_reader.skipCurrentElement();
}
}
2019-01-31 01:46:53 +01:00
void KMLParser::placemark(QList<TrackData> &tracks, QList<Area> &areas,
2022-09-01 00:49:21 +02:00
QVector<Waypoint> &waypoints, const QMap<QString, QPixmap> &icons)
{
QString name, desc, phone, address, id;
QDateTime timestamp;
2016-10-25 22:50:11 +02:00
while (_reader.readNextStartElement()) {
2018-08-27 22:25:55 +02:00
if (_reader.name() == QLatin1String("name"))
name = _reader.readElementText();
2018-08-27 22:25:55 +02:00
else if (_reader.name() == QLatin1String("description"))
desc = _reader.readElementText();
else if (_reader.name() == QLatin1String("phoneNumber"))
phone = _reader.readElementText();
else if (_reader.name() == QLatin1String("address"))
address = _reader.readElementText();
2018-08-27 22:25:55 +02:00
else if (_reader.name() == QLatin1String("TimeStamp"))
timestamp = timeStamp();
2018-08-27 22:25:55 +02:00
else if (_reader.name() == QLatin1String("MultiGeometry"))
2019-01-31 01:46:53 +01:00
multiGeometry(tracks, areas, waypoints, name, desc, timestamp);
2018-08-27 22:25:55 +02:00
else if (_reader.name() == QLatin1String("Point")) {
2017-07-27 19:47:46 +02:00
waypoints.append(Waypoint());
Waypoint &w = waypoints.last();
w.setName(name);
w.setDescription(desc);
w.setTimestamp(timestamp);
w.setAddress(address);
w.setPhone(phone);
if (!id.isNull())
w.setIcon(icons.value(id));
point(w);
2018-08-27 22:25:55 +02:00
} else if (_reader.name() == QLatin1String("LineString")
|| _reader.name() == QLatin1String("LinearRing")) {
2017-07-27 19:47:46 +02:00
tracks.append(TrackData());
TrackData &t = tracks.last();
2019-02-11 23:28:08 +01:00
t.append(SegmentData());
t.setName(name);
t.setDescription(desc);
2019-02-11 23:28:08 +01:00
lineString(t.last());
2018-08-27 22:25:55 +02:00
} else if (_reader.name() == QLatin1String("Track")) {
2017-07-27 19:47:46 +02:00
tracks.append(TrackData());
TrackData &t = tracks.last();
2019-02-11 23:28:08 +01:00
t.append(SegmentData());
t.setName(name);
t.setDescription(desc);
2019-02-11 23:28:08 +01:00
track(t.last());
2018-08-27 22:25:55 +02:00
} else if (_reader.name() == QLatin1String("MultiTrack")) {
tracks.append(TrackData());
TrackData &t = tracks.last();
t.setName(name);
t.setDescription(desc);
multiTrack(t);
2019-01-31 01:46:53 +01:00
} else if (_reader.name() == QLatin1String("Polygon")) {
areas.append(Area());
Area &a = areas.last();
a.setName(name);
a.setDescription(desc);
polygon(a);
} else if (_reader.name() == QLatin1String("styleUrl")) {
id = _reader.readElementText();
id = (id.at(0) == '#') ? id.right(id.size() - 1) : QString();
2016-10-27 22:33:35 +02:00
} else
2016-10-25 22:50:11 +02:00
_reader.skipCurrentElement();
}
}
void KMLParser::icon(const QDir &dir, const QString &id,
QMap<QString, QPixmap> &icons)
2016-10-25 22:50:11 +02:00
{
QString path;
2016-10-25 22:50:11 +02:00
while (_reader.readNextStartElement()) {
if (_reader.name() == QLatin1String("href"))
path = _reader.readElementText();
else
_reader.skipCurrentElement();
}
if (!path.isNull())
icons.insert(id, QPixmap(dir.absoluteFilePath(path)));
}
void KMLParser::iconStyle(const QDir &dir, const QString &id,
QMap<QString, QPixmap> &icons)
{
while (_reader.readNextStartElement()) {
if (_reader.name() == QLatin1String("Icon"))
icon(dir, id, icons);
else
_reader.skipCurrentElement();
}
}
void KMLParser::style(const QDir &dir, QMap<QString, QPixmap> &icons)
{
QString id = _reader.attributes().value("id").toString();
while (_reader.readNextStartElement()) {
if (_reader.name() == QLatin1String("IconStyle"))
iconStyle(dir, id, icons);
else
_reader.skipCurrentElement();
}
}
void KMLParser::folder(const QDir &dir, QList<TrackData> &tracks,
QList<Area> &areas, QVector<Waypoint> &waypoints,
2022-09-01 00:49:21 +02:00
const QMap<QString, QPixmap> &icons)
{
while (_reader.readNextStartElement()) {
if (_reader.name() == QLatin1String("Document"))
2022-09-01 00:49:21 +02:00
document(dir, tracks, areas, waypoints);
else if (_reader.name() == QLatin1String("Placemark"))
placemark(tracks, areas, waypoints, icons);
2018-08-27 22:25:55 +02:00
else if (_reader.name() == QLatin1String("Folder"))
folder(dir, tracks, areas, waypoints, icons);
else
_reader.skipCurrentElement();
}
}
void KMLParser::document(const QDir &dir, QList<TrackData> &tracks,
2022-09-01 00:49:21 +02:00
QList<Area> &areas, QVector<Waypoint> &waypoints)
{
2022-09-01 00:49:21 +02:00
QMap<QString, QPixmap> icons;
while (_reader.readNextStartElement()) {
if (_reader.name() == QLatin1String("Document"))
2022-09-01 00:49:21 +02:00
document(dir, tracks, areas, waypoints);
else if (_reader.name() == QLatin1String("Placemark"))
placemark(tracks, areas, waypoints, icons);
2018-08-27 22:25:55 +02:00
else if (_reader.name() == QLatin1String("Folder"))
folder(dir, tracks, areas, waypoints, icons);
else if (_reader.name() == QLatin1String("Style"))
style(dir, icons);
else
_reader.skipCurrentElement();
}
}
void KMLParser::kml(const QDir &dir, QList<TrackData> &tracks,
QList<Area> &areas, QVector<Waypoint> &waypoints)
{
while (_reader.readNextStartElement()) {
2018-08-27 22:25:55 +02:00
if (_reader.name() == QLatin1String("Document"))
2022-09-01 00:49:21 +02:00
document(dir, tracks, areas, waypoints);
2018-08-27 22:25:55 +02:00
else if (_reader.name() == QLatin1String("Placemark"))
2022-09-01 00:49:21 +02:00
placemark(tracks, areas, waypoints, QMap<QString, QPixmap>());
2018-08-27 22:25:55 +02:00
else if (_reader.name() == QLatin1String("Folder"))
2022-09-01 00:49:21 +02:00
folder(dir, tracks, areas, waypoints, QMap<QString, QPixmap>());
else
_reader.skipCurrentElement();
}
}
2017-07-27 19:47:46 +02:00
bool KMLParser::parse(QFile *file, QList<TrackData> &tracks,
2019-01-31 01:46:53 +01:00
QList<RouteData> &routes, QList<Area> &areas, QVector<Waypoint> &waypoints)
{
2017-07-27 19:47:46 +02:00
Q_UNUSED(routes);
uchar magic[4];
QFileInfo fi(*file);
2017-07-27 19:47:46 +02:00
_reader.clear();
if (file->read((char *)magic, 4) == 4 && readUInt(magic) == ZIP_MAGIC) {
QZipReader zip(fi.absoluteFilePath(), QIODevice::ReadOnly);
QTemporaryDir tempDir;
if (!zip.extractAll(tempDir.path()))
_reader.raiseError("Error extracting ZIP file");
else {
QDir zipDir(tempDir.path());
QFileInfoList files(zipDir.entryInfoList(QStringList("*.kml"),
QDir::Files));
if (files.isEmpty())
_reader.raiseError("No KML file found in ZIP file");
else {
QFile kmlFile(files.first().absoluteFilePath());
if (!kmlFile.open(QIODevice::ReadOnly))
_reader.raiseError("Error opening KML file");
else {
_reader.setDevice(&kmlFile);
if (_reader.readNextStartElement()) {
if (_reader.name() == QLatin1String("kml"))
kml(zipDir, tracks, areas, waypoints);
else
_reader.raiseError("Not a KML file");
}
}
}
}
} else {
file->reset();
_reader.setDevice(file);
if (_reader.readNextStartElement()) {
if (_reader.name() == QLatin1String("kml"))
kml(fi.absoluteDir(), tracks, areas, waypoints);
else
_reader.raiseError("Not a KML file");
}
}
return !_reader.error();
}