diff --git a/src/common/util.cpp b/src/common/util.cpp index e44a1439..2b8af469 100644 --- a/src/common/util.cpp +++ b/src/common/util.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #ifdef Q_OS_ANDROID #include #include @@ -139,3 +140,9 @@ QString Util::displayName(const QString &path) return path; #endif // Q_OS_ANDROID } + +const QTemporaryDir &Util::tempDir() +{ + static QTemporaryDir dir; + return dir; +} diff --git a/src/common/util.h b/src/common/util.h index 2b1e2b44..a34c0e49 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -3,12 +3,15 @@ #include +class QTemporaryDir; + namespace Util { int str2int(const char *str, int len); double niceNum(double x, bool round); QString file2name(const QString &path); QString displayName(const QString &path); + const QTemporaryDir &tempDir(); } #endif // UTIL_H diff --git a/src/data/gpiparser.cpp b/src/data/gpiparser.cpp index bf778a49..0f985b32 100644 --- a/src/data/gpiparser.cpp +++ b/src/data/gpiparser.cpp @@ -11,6 +11,7 @@ #include "common/garmin.h" #include "common/textcodec.h" #include "common/color.h" +#include "common/util.h" #include "address.h" #include "gpiparser.h" @@ -388,12 +389,6 @@ static quint32 readAddress(DataStream &stream, Waypoint &waypoint) return rs + rh.size; } -static const QTemporaryDir &tempDir() -{ - static QTemporaryDir dir; - return dir; -} - static quint32 readImageInfo(DataStream &stream, Waypoint &waypoint, const QString &fileName, int &imgId) { @@ -408,12 +403,12 @@ static quint32 readImageInfo(DataStream &stream, Waypoint &waypoint, ba.resize(size); stream.readRawData(ba.data(), ba.size()); - if (tempDir().isValid()) { + if (Util::tempDir().isValid()) { QBuffer buf(&ba); QImageReader ir(&buf); QByteArray id(fileName.toUtf8() + QByteArray::number(imgId++)); - QFile imgFile(tempDir().path() + "/" + QString("%0.%1").arg( + QFile imgFile(Util::tempDir().path() + "/" + QString("%0.%1").arg( QCryptographicHash::hash(id, QCryptographicHash::Sha1).toHex(), QString(ir.format()))); imgFile.open(QIODevice::WriteOnly); diff --git a/src/data/kmlparser.cpp b/src/data/kmlparser.cpp index c99d24ef..f9e9cfec 100644 --- a/src/data/kmlparser.cpp +++ b/src/data/kmlparser.cpp @@ -18,14 +18,9 @@ #include #include #include +#include "common/util.h" #include "kmlparser.h" -static const QTemporaryDir &tempDir() -{ - static QTemporaryDir dir; - return dir; -} - static bool isZIP(QFile *file) { quint32 magic; @@ -496,6 +491,9 @@ void KMLParser::multiGeometry(QList &tracks, QList &areas, QVector &waypoints, const QString &name, const QString &desc, const QDateTime ×tamp) { + TrackData *tp = 0; + Area *ap = 0; + while (_reader.readNextStartElement()) { if (_reader.name() == QLatin1String("Point")) { waypoints.append(Waypoint()); @@ -505,18 +503,22 @@ void KMLParser::multiGeometry(QList &tracks, QList &areas, w.setTimestamp(timestamp); point(w); } else if (_reader.name() == QLatin1String("LineString")) { - tracks.append(TrackData()); - TrackData &t = tracks.last(); - t.append(SegmentData()); - t.setName(name); - t.setDescription(desc); - lineString(t.last()); + if (!tp) { + tracks.append(TrackData()); + tp = &tracks.last(); + tp->setName(name); + tp->setDescription(desc); + } + tp->append(SegmentData()); + lineString(tp->last()); } else if (_reader.name() == QLatin1String("Polygon")) { - areas.append(Area()); - Area &a = areas.last(); - a.setName(name); - a.setDescription(desc); - polygon(a); + if (!ap) { + areas.append(Area()); + ap = &areas.last(); + ap->setName(name); + ap->setDescription(desc); + } + polygon(*ap); } else _reader.skipCurrentElement(); } @@ -525,65 +527,55 @@ void KMLParser::multiGeometry(QList &tracks, QList &areas, void KMLParser::photoOverlay(const Ctx &ctx, QVector &waypoints, QMap &icons) { - QString name, desc, phone, address, path, link, id; - QDateTime timestamp; + QString img, id; + Waypoint w; + static QRegularExpression re("\\$\\[[^\\]]+\\]"); while (_reader.readNextStartElement()) { if (_reader.name() == QLatin1String("name")) - name = _reader.readElementText(); + w.setName(_reader.readElementText()); else if (_reader.name() == QLatin1String("description")) - desc = _reader.readElementText(); + w.setDescription(_reader.readElementText()); else if (_reader.name() == QLatin1String("phoneNumber")) - phone = _reader.readElementText(); + w.setPhone(_reader.readElementText()); else if (_reader.name() == QLatin1String("address")) - address = _reader.readElementText(); + w.setAddress(_reader.readElementText()); else if (_reader.name() == QLatin1String("TimeStamp")) - timestamp = timeStamp(); - else if (_reader.name() == QLatin1String("Style")) + w.setTimestamp(timeStamp()); + else if (_reader.name() == QLatin1String("Style")) { style(ctx.dir, icons); - else if (_reader.name() == QLatin1String("Icon")) { - QString image(icon()); - - QRegularExpression re("\\$\\[[^\\]]+\\]"); - image.replace(re, "0"); - QUrl url(image); - - if (url.scheme() == "http" || url.scheme() == "https") - link = image; - else { - if (ctx.zip) { - if (tempDir().isValid()) { - QFileInfo fi(image); - QByteArray id(ctx.path.toUtf8() + image.toUtf8()); - path = tempDir().path() + "/" + QString("%0.%1").arg( - QCryptographicHash::hash(id, QCryptographicHash::Sha1) - .toHex(), QString(fi.suffix())); - - QFile::rename(ctx.dir.absoluteFilePath(image), path); - } - } else - path = ctx.dir.absoluteFilePath(image); - } - } else if (_reader.name() == QLatin1String("Point")) { - waypoints.append(Waypoint()); - Waypoint &w = waypoints.last(); - w.setName(name); - w.setDescription(desc); - w.setTimestamp(timestamp); - w.setAddress(address); - w.setPhone(phone); - w.setIcon(icons.value(id)); - if (!path.isNull()) - w.addImage(path); - if (!link.isNull()) - w.addLink(Link(link, "Photo Overlay")); + id = QString(); + } else if (_reader.name() == QLatin1String("StyleMap")) + styleMap(icons); + else if (_reader.name() == QLatin1String("Icon")) + img = icon(); + else if (_reader.name() == QLatin1String("Point")) point(w); - } else if (_reader.name() == QLatin1String("styleUrl")) { - id = _reader.readElementText(); - id = (id.at(0) == '#') ? id.right(id.size() - 1) : QString(); - } else + else if (_reader.name() == QLatin1String("styleUrl")) + id = styleUrl(); + else _reader.skipCurrentElement(); } + + if (!w.coordinates().isNull()) { + w.setIcon(icons.value(id)); + + img.replace(re, "0"); + if (!QUrl(img).scheme().isEmpty()) + w.addLink(Link(img, "Photo Overlay")); + else if (ctx.zip && Util::tempDir().isValid()) { + QFileInfo fi(img); + QByteArray id(ctx.path.toUtf8() + img.toUtf8()); + QString path(Util::tempDir().path() + "/" + QString("%0.%1") + .arg(QCryptographicHash::hash(id, QCryptographicHash::Sha1) + .toHex(), QString(fi.suffix()))); + QFile::rename(ctx.dir.absoluteFilePath(img), path); + w.addImage(path); + } else if (!ctx.zip) + w.addImage(ctx.dir.absoluteFilePath(img)); + + waypoints.append(w); + } } void KMLParser::placemark(const Ctx &ctx, QList &tracks, @@ -592,6 +584,9 @@ void KMLParser::placemark(const Ctx &ctx, QList &tracks, { QString name, desc, phone, address, id; QDateTime timestamp; + Waypoint *wp = 0; + TrackData *tp = 0; + Area *ap = 0; while (_reader.readNextStartElement()) { if (_reader.name() == QLatin1String("name")) @@ -604,53 +599,56 @@ void KMLParser::placemark(const Ctx &ctx, QList &tracks, address = _reader.readElementText(); else if (_reader.name() == QLatin1String("TimeStamp")) timestamp = timeStamp(); - else if (_reader.name() == QLatin1String("Style")) + else if (_reader.name() == QLatin1String("Style")) { style(ctx.dir, icons); + id = QString(); + } else if (_reader.name() == QLatin1String("StyleMap")) + styleMap(icons); else if (_reader.name() == QLatin1String("MultiGeometry")) multiGeometry(tracks, areas, waypoints, name, desc, timestamp); else if (_reader.name() == QLatin1String("Point")) { waypoints.append(Waypoint()); - Waypoint &w = waypoints.last(); - w.setName(name); - w.setDescription(desc); - w.setTimestamp(timestamp); - w.setAddress(address); - w.setPhone(phone); - w.setIcon(icons.value(id)); - point(w); + wp = &waypoints.last(); + point(*wp); } else if (_reader.name() == QLatin1String("LineString") || _reader.name() == QLatin1String("LinearRing")) { tracks.append(TrackData()); - TrackData &t = tracks.last(); - t.append(SegmentData()); - t.setName(name); - t.setDescription(desc); - lineString(t.last()); + tp = &tracks.last(); + tp->append(SegmentData()); + lineString(tp->last()); } else if (_reader.name() == QLatin1String("Track")) { tracks.append(TrackData()); - TrackData &t = tracks.last(); - t.append(SegmentData()); - t.setName(name); - t.setDescription(desc); - track(t.last()); + tp = &tracks.last(); + tp->append(SegmentData()); + track(tp->last()); } else if (_reader.name() == QLatin1String("MultiTrack")) { tracks.append(TrackData()); - TrackData &t = tracks.last(); - t.setName(name); - t.setDescription(desc); - multiTrack(t); + tp = &tracks.last(); + multiTrack(*tp); } 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(); - } else + ap = &areas.last(); + polygon(*ap); + } else if (_reader.name() == QLatin1String("styleUrl")) + id = styleUrl(); + else _reader.skipCurrentElement(); } + + if (wp) { + wp->setName(name); + wp->setDescription(desc); + wp->setTimestamp(timestamp); + wp->setAddress(address); + wp->setPhone(phone); + wp->setIcon(icons.value(id)); + } else if (tp) { + tp->setName(name); + tp->setDescription(desc); + } else if (ap) { + ap->setName(name); + ap->setDescription(desc); + } } QString KMLParser::icon() @@ -667,6 +665,12 @@ QString KMLParser::icon() return path; } +QString KMLParser::styleUrl() +{ + QString id(_reader.readElementText()); + return (id.at(0) == '#') ? id.right(id.size() - 1) : QString(); +} + void KMLParser::iconStyle(const QDir &dir, const QString &id, QMap &icons) { @@ -678,6 +682,35 @@ void KMLParser::iconStyle(const QDir &dir, const QString &id, } } +void KMLParser::styleMapPair(const QString &id, QMap &icons) +{ + QString key, url; + + while (_reader.readNextStartElement()) { + if (_reader.name() == QLatin1String("key")) + key = _reader.readElementText(); + else if (_reader.name() == QLatin1String("styleUrl")) + url = styleUrl(); + else + _reader.skipCurrentElement(); + } + + if (key == "normal") + icons.insert(id, icons.value(url)); +} + +void KMLParser::styleMap(QMap &icons) +{ + QString id = _reader.attributes().value("id").toString(); + + while (_reader.readNextStartElement()) { + if (_reader.name() == QLatin1String("Pair")) + styleMapPair(id, icons); + else + _reader.skipCurrentElement(); + } +} + void KMLParser::style(const QDir &dir, QMap &icons) { QString id = _reader.attributes().value("id").toString(); @@ -724,6 +757,8 @@ void KMLParser::document(const Ctx &ctx, QList &tracks, photoOverlay(ctx, waypoints, icons); else if (_reader.name() == QLatin1String("Style")) style(ctx.dir, icons); + else if (_reader.name() == QLatin1String("StyleMap")) + styleMap(icons); else _reader.skipCurrentElement(); } diff --git a/src/data/kmlparser.h b/src/data/kmlparser.h index 50c7840e..bc2fc716 100644 --- a/src/data/kmlparser.h +++ b/src/data/kmlparser.h @@ -58,7 +58,10 @@ private: qreal number(); QDateTime time(); QString icon(); + QString styleUrl(); void style(const QDir &dir, QMap &icons); + void styleMapPair(const QString &id, QMap &icons); + void styleMap(QMap &icons); void iconStyle(const QDir &dir, const QString &id, QMap &icons);