1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-11-28 13:41:16 +01:00

Improved IMG maps loading (lazy loading)

This commit is contained in:
Martin Tůma 2019-07-04 09:05:30 +02:00
parent 863aa3f542
commit b4cc88446a
12 changed files with 66 additions and 80 deletions

View File

@ -25,18 +25,6 @@ struct CTX
QList<IMG::Point> *points; QList<IMG::Point> *points;
}; };
#ifndef QT_NO_DEBUG
static QDebug operator<<(QDebug dbg, const QMap<QString, VectorTile*> &map)
{
dbg.nospace() << "TileMap(";
for (QMap<QString, VectorTile*>::const_iterator it = map.constBegin();
it != map.constEnd(); ++it)
dbg << "(" << it.key() << ", " << *(*it) << ")";
dbg << ")";
return dbg.space();
}
#endif // QT_NO_DEBUG
IMG::IMG(const QString &fileName) : _file(fileName), _valid(false) IMG::IMG(const QString &fileName) : _file(fileName), _valid(false)
{ {
if (!_file.open(QFile::ReadOnly)) { if (!_file.open(QFile::ReadOnly)) {
@ -141,7 +129,6 @@ IMG::IMG(const QString &fileName) : _file(fileName), _valid(false)
} }
// Create tile tree // Create tile tree
QSet<int> bits;
for (QMap<QString, VectorTile*>::iterator it = tileMap.begin(); for (QMap<QString, VectorTile*>::iterator it = tileMap.begin();
it != tileMap.end(); ++it) { it != tileMap.end(); ++it) {
CHECK((*it)->init()); CHECK((*it)->init());
@ -154,12 +141,7 @@ IMG::IMG(const QString &fileName) : _file(fileName), _valid(false)
_tileTree.Insert(min, max, *it); _tileTree.Insert(min, max, *it);
_bounds |= (*it)->bounds(); _bounds |= (*it)->bounds();
for (int i = 0; i < (*it)->bits().count(); i++)
bits.insert((*it)->bits().at(i));
} }
_bits = bits.toList();
qSort(_bits);
// Read TYP file if any // Read TYP file if any
if (!TYPMap.isEmpty()) { if (!TYPMap.isEmpty()) {
@ -195,17 +177,9 @@ static bool cb(VectorTile *tile, void *context)
} }
void IMG::objects(const RectC &rect, int bits, QList<Poly> *polygons, void IMG::objects(const RectC &rect, int bits, QList<Poly> *polygons,
QList<Poly> *lines, QList<Point> *points) const QList<Poly> *lines, QList<Point> *points)
{ {
int mb = _bits.first(); CTX ctx(rect, bits, polygons, lines, points);
for (int i = 0; i < _bits.size(); i++) {
if (_bits.at(i) > bits)
break;
else
mb = _bits.at(i);
}
CTX ctx(rect, mb, polygons, lines, points);
double min[2], max[2]; double min[2], max[2];
min[0] = rect.left(); min[0] = rect.left();

View File

@ -48,11 +48,12 @@ public:
IMG(const QString &fileName); IMG(const QString &fileName);
~IMG(); ~IMG();
QString fileName() const {return _file.fileName();}
const QString &name() const {return _name;} const QString &name() const {return _name;}
const RectC &bounds() const {return _bounds;} const RectC &bounds() const {return _bounds;}
Range zooms() const {return Range(_bits.first(), _bits.last());}
void objects(const RectC &rect, int bits, QList<Poly> *polygons, void objects(const RectC &rect, int bits, QList<Poly> *polygons,
QList<Poly> *lines, QList<Point> *points) const; QList<Poly> *lines, QList<Point> *points);
const Style &style() const {return _style;} const Style &style() const {return _style;}
bool isValid() const {return _valid;} bool isValid() const {return _valid;}
@ -63,11 +64,11 @@ private:
typedef RTree<VectorTile*, double, 2> TileTree; typedef RTree<VectorTile*, double, 2> TileTree;
QString fileName() const {return _file.fileName();}
int blockSize() const {return _blockSize;} int blockSize() const {return _blockSize;}
bool readBlock(int blockNum, QByteArray &data); bool readBlock(int blockNum, QByteArray &data);
qint64 read(char *data, qint64 maxSize); qint64 read(char *data, qint64 maxSize);
template<class T> bool readValue(T &val); template<class T> bool readValue(T &val);
bool init();
QFile _file; QFile _file;
quint8 _key; quint8 _key;
@ -78,7 +79,6 @@ private:
QString _name; QString _name;
RectC _bounds; RectC _bounds;
QList<int> _bits;
Style _style; Style _style;
bool _valid; bool _valid;

View File

@ -160,10 +160,8 @@ Label LBLFile::label8b(Handle &hdl, quint32 offset) const
Label LBLFile::label(Handle &hdl, quint32 offset, bool poi) Label LBLFile::label(Handle &hdl, quint32 offset, bool poi)
{ {
if (!_init) { if (!_size && !init())
if (!(_init = init()))
return QString(); return QString();
}
quint32 labelOffset; quint32 labelOffset;
if (poi) { if (poi) {

View File

@ -9,7 +9,9 @@ class QTextCodec;
class LBLFile : public SubFile class LBLFile : public SubFile
{ {
public: public:
LBLFile(IMG *img, quint32 size) : SubFile(img, size), _init(false) {} LBLFile(IMG *img, quint32 size)
: SubFile(img, size), _offset(0), _size(0), _poiOffset(0), _poiSize(0),
_multiplier(0), _encoding(0), _codec(0) {}
Label label(Handle &hdl, quint32 offset, bool poi = false); Label label(Handle &hdl, quint32 offset, bool poi = false);
@ -26,8 +28,6 @@ private:
quint8 _multiplier; quint8 _multiplier;
quint8 _encoding; quint8 _encoding;
QTextCodec *_codec; QTextCodec *_codec;
bool _init;
}; };
#endif // LBLFILE_H #endif // LBLFILE_H

View File

@ -404,10 +404,8 @@ void RGNFile::objects(const RectC &rect, const SubDiv *subdiv, LBLFile *lbl,
{ {
Handle rgnHdl, lblHdl, netHdl; Handle rgnHdl, lblHdl, netHdl;
if (!_init) { if (!_size && !init())
if (!(_init = init()))
return; return;
}
QVector<RGNFile::Segment> seg(segments(rgnHdl, subdiv)); QVector<RGNFile::Segment> seg(segments(rgnHdl, subdiv));
for (int i = 0; i < seg.size(); i++) { for (int i = 0; i < seg.size(); i++) {
@ -438,10 +436,8 @@ void RGNFile::extObjects(const RectC &rect, const SubDiv *subdiv, LBLFile *lbl,
{ {
Handle rgnHdl, lblHdl; Handle rgnHdl, lblHdl;
if (!_init) { if (!_size && !init())
if (!(_init = init()))
return; return;
}
if (polygons && subdiv->polygonsOffset() != subdiv->polygonsEnd()) { if (polygons && subdiv->polygonsOffset() != subdiv->polygonsEnd()) {
quint32 start = _polygonsOffset + subdiv->polygonsOffset(); quint32 start = _polygonsOffset + subdiv->polygonsOffset();

View File

@ -11,7 +11,10 @@ class NETFile;
class RGNFile : public SubFile class RGNFile : public SubFile
{ {
public: public:
RGNFile(IMG *img, quint32 size) : SubFile(img, size), _init(false) {} RGNFile(IMG *img, quint32 size)
: SubFile(img, size), _offset(0), _size(0), _polygonsOffset(0),
_polygonsSize(), _linesOffset(), _linesSize(), _pointsOffset(),
_pointsSize() {}
void objects(const RectC &rect, const SubDiv *subdiv, LBLFile *lbl, void objects(const RectC &rect, const SubDiv *subdiv, LBLFile *lbl,
NETFile *net, QList<IMG::Poly> *polygons, QList<IMG::Poly> *lines, NETFile *net, QList<IMG::Poly> *polygons, QList<IMG::Poly> *lines,
@ -96,8 +99,6 @@ private:
quint32 _linesSize; quint32 _linesSize;
quint32 _pointsOffset; quint32 _pointsOffset;
quint32 _pointsSize; quint32 _pointsSize;
bool _init;
}; };
#ifndef QT_NO_DEBUG #ifndef QT_NO_DEBUG

View File

@ -9,16 +9,6 @@ struct MapLevel {
quint16 subdivs; quint16 subdivs;
}; };
#ifndef QT_NO_DEBUG
static QDebug operator<<(QDebug dbg, const MapLevel &ml)
{
bool inherited = ml.level & 0x80 ? true : false;
dbg.nospace() << "MapLevel(" << (ml.level & 0x7F) << ", " << inherited
<< ", " << ml.bits << ", " << ml.subdivs << ")";
return dbg.space();
}
#endif // QT_NO_DEBUG
static void unlock(quint8 *dst, const quint8 *src, quint32 size, quint32 key) static void unlock(quint8 *dst, const quint8 *src, quint32 size, quint32 key)
{ {
static const unsigned char shuf[] = { static const unsigned char shuf[] = {
@ -67,12 +57,6 @@ TREFile::~TREFile()
bool TREFile::init() bool TREFile::init()
{ {
Handle hdl; Handle hdl;
quint8 locked;
quint16 hdrLen;
if (!(isValid() && seek(hdl, 0) && readUInt16(hdl, hdrLen)
&& seek(hdl, 0x0D) && readByte(hdl, locked)))
return false;
// Tile bounds // Tile bounds
qint32 north, east, south, west; qint32 north, east, south, west;
@ -82,9 +66,23 @@ bool TREFile::init()
_bounds = RectC(Coordinates(toWGS84(west), toWGS84(north)), _bounds = RectC(Coordinates(toWGS84(west), toWGS84(north)),
Coordinates(toWGS84(east), toWGS84(south))); Coordinates(toWGS84(east), toWGS84(south)));
return true;
}
bool TREFile::init2()
{
Handle hdl;
quint8 locked;
quint16 hdrLen;
if (!(seek(hdl, 0) && readUInt16(hdl, hdrLen)
&& seek(hdl, 0x0D) && readByte(hdl, locked)))
return false;
quint32 levelsOffset, levelsSize, subdivOffset, subdivSize; quint32 levelsOffset, levelsSize, subdivOffset, subdivSize;
if (!(readUInt32(hdl, levelsOffset) && readUInt32(hdl, levelsSize) if (!(seek(hdl, 0x21) && readUInt32(hdl, levelsOffset)
&& readUInt32(hdl, subdivOffset) && readUInt32(hdl, subdivSize))) && readUInt32(hdl, levelsSize) && readUInt32(hdl, subdivOffset)
&& readUInt32(hdl, subdivSize)))
return false; return false;
quint32 extOffset, extSize = 0; quint32 extOffset, extSize = 0;
@ -199,9 +197,27 @@ bool TREFile::init()
} }
} }
_levels = _subdivs.keys();
return true; return true;
} }
int TREFile::level(int bits)
{
if (_levels.isEmpty() && !init2())
return -1;
int l = _levels.first();
for (int i = 0; i < _levels.size(); i++) {
if (_levels.at(i) > bits)
break;
else
l = _levels.at(i);
}
return l;
}
static bool cb(SubDiv *subdiv, void *context) static bool cb(SubDiv *subdiv, void *context)
{ {
QList<SubDiv*> *list = (QList<SubDiv*>*)context; QList<SubDiv*> *list = (QList<SubDiv*>*)context;
@ -209,9 +225,10 @@ static bool cb(SubDiv *subdiv, void *context)
return true; return true;
} }
QList<SubDiv*> TREFile::subdivs(const RectC &rect, int bits) const QList<SubDiv*> TREFile::subdivs(const RectC &rect, int bits)
{ {
QList<SubDiv*> list; QList<SubDiv*> list;
SubDivTree *tree = _subdivs.value(level(bits));
double min[2], max[2]; double min[2], max[2];
min[0] = rect.left(); min[0] = rect.left();
@ -219,7 +236,8 @@ QList<SubDiv*> TREFile::subdivs(const RectC &rect, int bits) const
max[0] = rect.right(); max[0] = rect.right();
max[1] = rect.top(); max[1] = rect.top();
_subdivs.value(bits)->Search(min, max, cb, &list); if (tree)
tree->Search(min, max, cb, &list);
return list; return list;
} }

View File

@ -19,18 +19,19 @@ public:
bool init(); bool init();
const RectC &bounds() const {return _bounds;} const RectC &bounds() const {return _bounds;}
const QList<int> bits() const {return _subdivs.keys();} QList<SubDiv*> subdivs(const RectC &rect, int bits);
QList<SubDiv*> subdivs(const RectC &rect, int bits) const;
private: private:
typedef RTree<SubDiv*, double, 2> SubDivTree; typedef RTree<SubDiv*, double, 2> SubDivTree;
bool init2();
int level(int bits);
bool parsePoly(Handle hdl, quint32 pos, const QMap<int, int> &level2bits, bool parsePoly(Handle hdl, quint32 pos, const QMap<int, int> &level2bits,
QMap<quint32, int> &map); QMap<quint32, int> &map);
bool parsePoints(Handle hdl, quint32 pos, const QMap<int, int> &level2bits); bool parsePoints(Handle hdl, quint32 pos, const QMap<int, int> &level2bits);
RectC _bounds; RectC _bounds;
QList<int> _levels;
QMap<int, SubDivTree*> _subdivs; QMap<int, SubDivTree*> _subdivs;
}; };

View File

@ -38,7 +38,8 @@ SubFile *VectorTile::addFile(IMG *img, SubFile::Type type, quint32 size)
bool VectorTile::init() bool VectorTile::init()
{ {
if (!(_tre && _tre->init() && _rgn && _rgn->isValid())) if (!(_tre && _tre->isValid() && _tre->init() && _rgn
&& _rgn->isValid()))
return false; return false;
if (_lbl && !_lbl->isValid()) if (_lbl && !_lbl->isValid())
return false; return false;

View File

@ -16,7 +16,6 @@ public:
bool init(); bool init();
const RectC &bounds() const {return _tre->bounds();} const RectC &bounds() const {return _tre->bounds();}
const QList<int> bits() const {return _tre->bits();}
SubFile *file(SubFile::Type type); SubFile *file(SubFile::Type type);
SubFile *addFile(IMG *img, SubFile::Type type, quint32 size); SubFile *addFile(IMG *img, SubFile::Type type, quint32 size);

View File

@ -159,15 +159,14 @@ static int minShieldZoom(Label::Shield::Type type)
IMGMap::IMGMap(const QString &fileName, QObject *parent) IMGMap::IMGMap(const QString &fileName, QObject *parent)
: Map(parent), _fileName(fileName), _img(fileName), : Map(parent), _img(fileName), _projection(PCS::pcs(3857)), _valid(false)
_projection(PCS::pcs(3857)), _valid(false)
{ {
if (!_img.isValid()) { if (!_img.isValid()) {
_errorString = _img.errorString(); _errorString = _img.errorString();
return; return;
} }
_zooms = Range(qMin(_img.zooms().min(), 12), 28); _zooms = Range(12, 28);
_zoom = _zooms.min(); _zoom = _zooms.min();
updateTransform(); updateTransform();
@ -489,7 +488,7 @@ void IMGMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
for (int j = 0; j < height; j++) { for (int j = 0; j < height; j++) {
QPixmap pm; QPixmap pm;
QPoint ttl(tl.x() + i * TILE_SIZE, tl.y() + j * TILE_SIZE); QPoint ttl(tl.x() + i * TILE_SIZE, tl.y() + j * TILE_SIZE);
QString key = _fileName + "-" + QString::number(_zoom) + "_" QString key = _img.fileName() + "-" + QString::number(_zoom) + "_"
+ QString::number(ttl.x()) + "_" + QString::number(ttl.y()); + QString::number(ttl.x()) + "_" + QString::number(ttl.y());
if (QPixmapCache::find(key, pm)) if (QPixmapCache::find(key, pm))
painter->drawPixmap(ttl, pm); painter->drawPixmap(ttl, pm);

View File

@ -51,7 +51,6 @@ private:
QList<TextItem*> &textItems); QList<TextItem*> &textItems);
void processPoints(QList<IMG::Point> &points, QList<TextItem*> &textItems); void processPoints(QList<IMG::Point> &points, QList<TextItem*> &textItems);
QString _fileName;
IMG _img; IMG _img;
int _zoom; int _zoom;
Range _zooms; Range _zooms;