1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-10-06 14:53:21 +02: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;
};
#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)
{
if (!_file.open(QFile::ReadOnly)) {
@ -141,7 +129,6 @@ IMG::IMG(const QString &fileName) : _file(fileName), _valid(false)
}
// Create tile tree
QSet<int> bits;
for (QMap<QString, VectorTile*>::iterator it = tileMap.begin();
it != tileMap.end(); ++it) {
CHECK((*it)->init());
@ -154,12 +141,7 @@ IMG::IMG(const QString &fileName) : _file(fileName), _valid(false)
_tileTree.Insert(min, max, *it);
_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
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,
QList<Poly> *lines, QList<Point> *points) const
QList<Poly> *lines, QList<Point> *points)
{
int mb = _bits.first();
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);
CTX ctx(rect, bits, polygons, lines, points);
double min[2], max[2];
min[0] = rect.left();

View File

@ -48,11 +48,12 @@ public:
IMG(const QString &fileName);
~IMG();
QString fileName() const {return _file.fileName();}
const QString &name() const {return _name;}
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,
QList<Poly> *lines, QList<Point> *points) const;
QList<Poly> *lines, QList<Point> *points);
const Style &style() const {return _style;}
bool isValid() const {return _valid;}
@ -63,11 +64,11 @@ private:
typedef RTree<VectorTile*, double, 2> TileTree;
QString fileName() const {return _file.fileName();}
int blockSize() const {return _blockSize;}
bool readBlock(int blockNum, QByteArray &data);
qint64 read(char *data, qint64 maxSize);
template<class T> bool readValue(T &val);
bool init();
QFile _file;
quint8 _key;
@ -78,7 +79,6 @@ private:
QString _name;
RectC _bounds;
QList<int> _bits;
Style _style;
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)
{
if (!_init) {
if (!(_init = init()))
return QString();
}
if (!_size && !init())
return QString();
quint32 labelOffset;
if (poi) {

View File

@ -9,7 +9,9 @@ class QTextCodec;
class LBLFile : public SubFile
{
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);
@ -26,8 +28,6 @@ private:
quint8 _multiplier;
quint8 _encoding;
QTextCodec *_codec;
bool _init;
};
#endif // LBLFILE_H

View File

@ -404,10 +404,8 @@ void RGNFile::objects(const RectC &rect, const SubDiv *subdiv, LBLFile *lbl,
{
Handle rgnHdl, lblHdl, netHdl;
if (!_init) {
if (!(_init = init()))
return;
}
if (!_size && !init())
return;
QVector<RGNFile::Segment> seg(segments(rgnHdl, subdiv));
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;
if (!_init) {
if (!(_init = init()))
return;
}
if (!_size && !init())
return;
if (polygons && subdiv->polygonsOffset() != subdiv->polygonsEnd()) {
quint32 start = _polygonsOffset + subdiv->polygonsOffset();

View File

@ -11,7 +11,10 @@ class NETFile;
class RGNFile : public SubFile
{
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,
NETFile *net, QList<IMG::Poly> *polygons, QList<IMG::Poly> *lines,
@ -96,8 +99,6 @@ private:
quint32 _linesSize;
quint32 _pointsOffset;
quint32 _pointsSize;
bool _init;
};
#ifndef QT_NO_DEBUG

View File

@ -9,16 +9,6 @@ struct MapLevel {
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 const unsigned char shuf[] = {
@ -67,12 +57,6 @@ TREFile::~TREFile()
bool TREFile::init()
{
Handle hdl;
quint8 locked;
quint16 hdrLen;
if (!(isValid() && seek(hdl, 0) && readUInt16(hdl, hdrLen)
&& seek(hdl, 0x0D) && readByte(hdl, locked)))
return false;
// Tile bounds
qint32 north, east, south, west;
@ -82,9 +66,23 @@ bool TREFile::init()
_bounds = RectC(Coordinates(toWGS84(west), toWGS84(north)),
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;
if (!(readUInt32(hdl, levelsOffset) && readUInt32(hdl, levelsSize)
&& readUInt32(hdl, subdivOffset) && readUInt32(hdl, subdivSize)))
if (!(seek(hdl, 0x21) && readUInt32(hdl, levelsOffset)
&& readUInt32(hdl, levelsSize) && readUInt32(hdl, subdivOffset)
&& readUInt32(hdl, subdivSize)))
return false;
quint32 extOffset, extSize = 0;
@ -199,9 +197,27 @@ bool TREFile::init()
}
}
_levels = _subdivs.keys();
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)
{
QList<SubDiv*> *list = (QList<SubDiv*>*)context;
@ -209,9 +225,10 @@ static bool cb(SubDiv *subdiv, void *context)
return true;
}
QList<SubDiv*> TREFile::subdivs(const RectC &rect, int bits) const
QList<SubDiv*> TREFile::subdivs(const RectC &rect, int bits)
{
QList<SubDiv*> list;
SubDivTree *tree = _subdivs.value(level(bits));
double min[2], max[2];
min[0] = rect.left();
@ -219,7 +236,8 @@ QList<SubDiv*> TREFile::subdivs(const RectC &rect, int bits) const
max[0] = rect.right();
max[1] = rect.top();
_subdivs.value(bits)->Search(min, max, cb, &list);
if (tree)
tree->Search(min, max, cb, &list);
return list;
}

View File

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

View File

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

View File

@ -16,7 +16,6 @@ public:
bool init();
const RectC &bounds() const {return _tre->bounds();}
const QList<int> bits() const {return _tre->bits();}
SubFile *file(SubFile::Type type);
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)
: Map(parent), _fileName(fileName), _img(fileName),
_projection(PCS::pcs(3857)), _valid(false)
: Map(parent), _img(fileName), _projection(PCS::pcs(3857)), _valid(false)
{
if (!_img.isValid()) {
_errorString = _img.errorString();
return;
}
_zooms = Range(qMin(_img.zooms().min(), 12), 28);
_zooms = Range(12, 28);
_zoom = _zooms.min();
updateTransform();
@ -489,7 +488,7 @@ void IMGMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
for (int j = 0; j < height; j++) {
QPixmap pm;
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());
if (QPixmapCache::find(key, pm))
painter->drawPixmap(ttl, pm);

View File

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