mirror of
https://github.com/tumic0/GPXSee.git
synced 2024-11-24 03:35:53 +01:00
Various KML/KMZ parsing fixes and code cleanup
This commit is contained in:
parent
b156e25023
commit
fafe6c4b03
@ -1,6 +1,7 @@
|
||||
#include <cctype>
|
||||
#include <cmath>
|
||||
#include <QFileInfo>
|
||||
#include <QTemporaryDir>
|
||||
#ifdef Q_OS_ANDROID
|
||||
#include <QUrl>
|
||||
#include <QCoreApplication>
|
||||
@ -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;
|
||||
}
|
||||
|
@ -3,12 +3,15 @@
|
||||
|
||||
#include <QString>
|
||||
|
||||
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
|
||||
|
@ -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);
|
||||
|
@ -18,14 +18,9 @@
|
||||
#include <QUrl>
|
||||
#include <QRegularExpression>
|
||||
#include <private/qzipreader_p.h>
|
||||
#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<TrackData> &tracks, QList<Area> &areas,
|
||||
QVector<Waypoint> &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<TrackData> &tracks, QList<Area> &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<TrackData> &tracks, QList<Area> &areas,
|
||||
void KMLParser::photoOverlay(const Ctx &ctx, QVector<Waypoint> &waypoints,
|
||||
QMap<QString, QPixmap> &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<TrackData> &tracks,
|
||||
@ -592,6 +584,9 @@ void KMLParser::placemark(const Ctx &ctx, QList<TrackData> &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<TrackData> &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<QString, QPixmap> &icons)
|
||||
{
|
||||
@ -678,6 +682,35 @@ void KMLParser::iconStyle(const QDir &dir, const QString &id,
|
||||
}
|
||||
}
|
||||
|
||||
void KMLParser::styleMapPair(const QString &id, QMap<QString, QPixmap> &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<QString, QPixmap> &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<QString, QPixmap> &icons)
|
||||
{
|
||||
QString id = _reader.attributes().value("id").toString();
|
||||
@ -724,6 +757,8 @@ void KMLParser::document(const Ctx &ctx, QList<TrackData> &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();
|
||||
}
|
||||
|
@ -58,7 +58,10 @@ private:
|
||||
qreal number();
|
||||
QDateTime time();
|
||||
QString icon();
|
||||
QString styleUrl();
|
||||
void style(const QDir &dir, QMap<QString, QPixmap> &icons);
|
||||
void styleMapPair(const QString &id, QMap<QString, QPixmap> &icons);
|
||||
void styleMap(QMap<QString, QPixmap> &icons);
|
||||
void iconStyle(const QDir &dir, const QString &id,
|
||||
QMap<QString, QPixmap> &icons);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user