1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2025-02-26 04:00:49 +01:00

Atlas loading optimization

This commit is contained in:
Martin Tůma 2017-03-27 02:41:30 +02:00
parent 0c7601c831
commit c1844f9557
4 changed files with 105 additions and 31 deletions

View File

@ -35,13 +35,12 @@ bool Atlas::isAtlas(const QFileInfoList &files)
for (int i = 0; i < files.count(); i++) { for (int i = 0; i < files.count(); i++) {
const QString &fileName = files.at(i).fileName(); const QString &fileName = files.at(i).fileName();
if (fileName.endsWith(".tar")) { if (fileName.endsWith(".tar")) {
Tar tar; if (!_tar.load(files.at(i).absoluteFilePath())) {
if (!tar.load(files.at(i).absoluteFilePath())) {
qWarning("%s: %s: error loading tar file", qPrintable(_name), qWarning("%s: %s: error loading tar file", qPrintable(_name),
qPrintable(fileName)); qPrintable(fileName));
return false; return false;
} }
QStringList tarFiles = tar.files(); QStringList tarFiles = _tar.files();
for (int j = 0; j < tarFiles.size(); j++) for (int j = 0; j < tarFiles.size(); j++)
if (tarFiles.at(j).endsWith(".tba")) if (tarFiles.at(j).endsWith(".tba"))
return true; return true;
@ -126,7 +125,11 @@ Atlas::Atlas(const QString &path, QObject *parent) : Map(parent)
QFileInfoList maps = zdir.entryInfoList(QDir::Dirs QFileInfoList maps = zdir.entryInfoList(QDir::Dirs
| QDir::NoDotAndDotDot); | QDir::NoDotAndDotDot);
for (int i = 0; i < maps.count(); i++) { for (int i = 0; i < maps.count(); i++) {
OfflineMap *map = new OfflineMap(maps.at(i).absoluteFilePath()); OfflineMap *map;
if (_tar.isOpen())
map = new OfflineMap(_tar, maps.at(i).absoluteFilePath(), this);
else
map = new OfflineMap(maps.at(i).absoluteFilePath(), this);
if (map->isValid()) if (map->isValid())
_maps.append(map); _maps.append(map);
} }
@ -253,6 +256,8 @@ void Atlas::draw(QPainter *painter, const QRectF &rect)
const QPointF offset = _bounds.at(i).second.topLeft(); const QPointF offset = _bounds.at(i).second.topLeft();
QRectF pr = QRectF(ir.topLeft() - offset, ir.size()); QRectF pr = QRectF(ir.topLeft() - offset, ir.size());
map->load();
painter->translate(offset); painter->translate(offset);
map->draw(painter, pr); map->draw(painter, pr);
painter->translate(-offset); painter->translate(-offset);

View File

@ -38,6 +38,7 @@ private:
QString _name; QString _name;
bool _valid; bool _valid;
Tar _tar;
QList<OfflineMap*> _maps; QList<OfflineMap*> _maps;
QVector<QPair<int, int> > _zooms; QVector<QPair<int, int> > _zooms;
QVector<QPair<QRectF, QRectF> > _bounds; QVector<QPair<QRectF, QRectF> > _bounds;

View File

@ -82,8 +82,11 @@ int OfflineMap::parseMapFile(QIODevice &device, QList<ReferencePoint> &points)
bool OfflineMap::computeTransformation(const QList<ReferencePoint> &points) bool OfflineMap::computeTransformation(const QList<ReferencePoint> &points)
{ {
if (points.count() < 2) if (points.count() < 2) {
qWarning("%s: insufficient number of reference points",
qPrintable(_name));
return false; return false;
}
Matrix c(3, 2); Matrix c(3, 2);
c.zeroize(); c.zeroize();
@ -118,8 +121,10 @@ bool OfflineMap::computeTransformation(const QList<ReferencePoint> &points)
} }
Matrix M = Q.augemented(c); Matrix M = Q.augemented(c);
if (!M.eliminate()) if (!M.eliminate()) {
qWarning("%s: singular transformation matrix", qPrintable(_name));
return false; return false;
}
_transform = QTransform(M.m(0,3), M.m(1,3), M.m(0,4), M.m(1,4), _transform = QTransform(M.m(0,3), M.m(1,3), M.m(0,4), M.m(1,4),
M.m(2,3), M.m(2,4)); M.m(2,3), M.m(2,4));
@ -129,8 +134,7 @@ bool OfflineMap::computeTransformation(const QList<ReferencePoint> &points)
bool OfflineMap::computeResolution(QList<ReferencePoint> &points) bool OfflineMap::computeResolution(QList<ReferencePoint> &points)
{ {
if (points.count() < 2) Q_ASSERT(points.count() >= 2);
return false;
int maxLon = 0, minLon = 0, maxLat = 0, minLat = 0; int maxLon = 0, minLon = 0, maxLat = 0, minLat = 0;
qreal dLon, pLon, dLat, pLat; qreal dLon, pLon, dLat, pLat;
@ -173,7 +177,8 @@ bool OfflineMap::getImageInfo(const QString &path)
return true; return true;
} }
bool OfflineMap::getTileInfo(const QStringList &tiles, const QString &path) bool OfflineMap::getTileInfo(const QStringList &tiles,
const QString &path)
{ {
if (!_size.isValid()) { if (!_size.isValid()) {
qWarning("%s: missing total image size (IWH)", qPrintable(_name)); qWarning("%s: missing total image size (IWH)", qPrintable(_name));
@ -190,7 +195,7 @@ bool OfflineMap::getTileInfo(const QStringList &tiles, const QString &path)
if (tiles.at(i).contains(rx)) { if (tiles.at(i).contains(rx)) {
_tileName = QString(tiles.at(i)).replace(rx, "_%1_%2."); _tileName = QString(tiles.at(i)).replace(rx, "_%1_%2.");
if (_tar.isOpen()) { if (path.isNull()) {
QByteArray ba = _tar.file(tiles.at(i)); QByteArray ba = _tar.file(tiles.at(i));
QBuffer buffer(&ba); QBuffer buffer(&ba);
_tileSize = QImageReader(&buffer).size(); _tileSize = QImageReader(&buffer).size();
@ -214,12 +219,27 @@ bool OfflineMap::getTileInfo(const QStringList &tiles, const QString &path)
return false; return false;
} }
bool OfflineMap::mapLoaded(int res)
{
if (res) {
if (res == -2)
qWarning("%s: no map file found", qPrintable(_name));
else if (res == -1)
qWarning("%s: error opening map file", qPrintable(_name));
else
qWarning("%s: map file parse error on line: %d", qPrintable(_name),
res);
return false;
}
return true;
}
OfflineMap::OfflineMap(const QString &path, QObject *parent) : Map(parent) OfflineMap::OfflineMap(const QString &path, QObject *parent) : Map(parent)
{ {
int errorLine = -2; int errorLine = -2;
QList<ReferencePoint> points; QList<ReferencePoint> points;
_valid = false; _valid = false;
QFileInfo fi(path); QFileInfo fi(path);
@ -241,6 +261,7 @@ OfflineMap::OfflineMap(const QString &path, QObject *parent) : Map(parent)
QByteArray ba = _tar.file(tarFiles.at(j)); QByteArray ba = _tar.file(tarFiles.at(j));
QBuffer buffer(&ba); QBuffer buffer(&ba);
errorLine = parseMapFile(buffer, points); errorLine = parseMapFile(buffer, points);
_imgPath = QString();
break; break;
} }
} }
@ -251,21 +272,11 @@ OfflineMap::OfflineMap(const QString &path, QObject *parent) : Map(parent)
break; break;
} }
} }
if (errorLine) { if (!mapLoaded(errorLine))
if (errorLine == -2)
qWarning("%s: no map file found", qPrintable(_name));
else if (errorLine == -1)
qWarning("%s: error opening map file", qPrintable(_name));
else
qWarning("%s: map file parse error on line: %d", qPrintable(_name),
errorLine);
return; return;
}
if (!computeTransformation(points)) { if (!computeTransformation(points))
qWarning("%s: error computing map transformation", qPrintable(_name));
return; return;
}
computeResolution(points); computeResolution(points);
if (_tar.isOpen()) { if (_tar.isOpen()) {
@ -274,8 +285,9 @@ OfflineMap::OfflineMap(const QString &path, QObject *parent) : Map(parent)
} else { } else {
QDir set(fi.absoluteFilePath() + "/" + "set"); QDir set(fi.absoluteFilePath() + "/" + "set");
if (set.exists()) { if (set.exists()) {
if (!getTileInfo(set.entryList(), set.absolutePath())) if (!getTileInfo(set.entryList(), set.canonicalPath()))
return; return;
_imgPath = QString();
} else { } else {
if (!getImageInfo(fi.absoluteFilePath())) if (!getImageInfo(fi.absoluteFilePath()))
return; return;
@ -286,20 +298,73 @@ OfflineMap::OfflineMap(const QString &path, QObject *parent) : Map(parent)
_valid = true; _valid = true;
} }
void OfflineMap::load() OfflineMap::OfflineMap(Tar &tar, const QString &path, QObject *parent)
: Map(parent)
{ {
if (_tileSize.isValid()) int errorLine = -2;
QList<ReferencePoint> points;
_valid = false;
QFileInfo fi(path);
_name = fi.fileName();
QFileInfo li(fi.absoluteDir().dirName());
QString prefix = li.fileName() + "/" + fi.fileName() + "/";
QStringList tarFiles = tar.files();
for (int j = 0; j < tarFiles.size(); j++) {
if (tarFiles.at(j).startsWith(prefix)) {
QByteArray ba = tar.file(tarFiles.at(j));
QBuffer buffer(&ba);
errorLine = parseMapFile(buffer, points);
break;
}
}
if (!mapLoaded(errorLine))
return; return;
if (!computeTransformation(points))
return;
computeResolution(points);
QDir dir(path);
QFileInfoList mapFiles = dir.entryInfoList(QDir::Files);
for (int i = 0; i < mapFiles.count(); i++) {
const QString &fileName = mapFiles.at(i).absoluteFilePath();
if (fileName.endsWith(".tar"))
_tarPath = fileName;
}
_imgPath = QString();
_img = 0;
_valid = true;
}
void OfflineMap::load()
{
if (!_tarPath.isNull() && !_tileSize.isValid()) {
if (!_tar.load(_tarPath)) {
qWarning("%s: %s: error loading tar file", qPrintable(_name),
qPrintable(_tarPath));
return;
}
getTileInfo(_tar.files());
return;
}
if (!_img && !_imgPath.isNull()) {
_img = new QImage(_imgPath); _img = new QImage(_imgPath);
if (_img->isNull()) if (_img->isNull())
qWarning("%s: error loading map image", qPrintable(_imgPath)); qWarning("%s: error loading map image", qPrintable(_imgPath));
}
} }
void OfflineMap::unload() void OfflineMap::unload()
{ {
if (_img) if (_img) {
delete _img; delete _img;
_img = 0;
}
} }
QRectF OfflineMap::bounds() const QRectF OfflineMap::bounds() const
@ -369,7 +434,7 @@ void OfflineMap::draw(QPainter *painter, const QRectF &rect)
} }
} }
} else { } else {
if (_img->isNull()) if (!_img || _img->isNull())
painter->fillRect(rect, Qt::white); painter->fillRect(rect, Qt::white);
else { else {
QPoint p = rect.topLeft().toPoint(); QPoint p = rect.topLeft().toPoint();

View File

@ -15,6 +15,7 @@ class OfflineMap : public Map
public: public:
OfflineMap(const QString &path, QObject *parent = 0); OfflineMap(const QString &path, QObject *parent = 0);
OfflineMap(Tar &tar, const QString &path, QObject *parent = 0);
const QString &name() const {return _name;} const QString &name() const {return _name;}
@ -40,6 +41,7 @@ private:
typedef QPair<QPoint, Coordinates> ReferencePoint; typedef QPair<QPoint, Coordinates> ReferencePoint;
int parseMapFile(QIODevice &device, QList<ReferencePoint> &points); int parseMapFile(QIODevice &device, QList<ReferencePoint> &points);
bool mapLoaded(int res);
bool computeTransformation(const QList<ReferencePoint> &points); bool computeTransformation(const QList<ReferencePoint> &points);
bool computeResolution(QList<ReferencePoint> &points); bool computeResolution(QList<ReferencePoint> &points);
bool getTileInfo(const QStringList &tiles, const QString &path = QString()); bool getTileInfo(const QStringList &tiles, const QString &path = QString());
@ -51,6 +53,7 @@ private:
qreal _resolution; qreal _resolution;
Tar _tar; Tar _tar;
QString _tarPath;
QImage *_img; QImage *_img;
QString _imgPath; QString _imgPath;
QSize _tileSize; QSize _tileSize;