mirror of
https://github.com/tumic0/GPXSee.git
synced 2024-11-30 22:51:16 +01:00
Improved IMG maps loading (lazy loading)
This commit is contained in:
parent
863aa3f542
commit
b4cc88446a
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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()))
|
||||
if (!_size && !init())
|
||||
return QString();
|
||||
}
|
||||
|
||||
quint32 labelOffset;
|
||||
if (poi) {
|
||||
|
@ -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
|
||||
|
@ -404,10 +404,8 @@ void RGNFile::objects(const RectC &rect, const SubDiv *subdiv, LBLFile *lbl,
|
||||
{
|
||||
Handle rgnHdl, lblHdl, netHdl;
|
||||
|
||||
if (!_init) {
|
||||
if (!(_init = init()))
|
||||
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()))
|
||||
if (!_size && !init())
|
||||
return;
|
||||
}
|
||||
|
||||
if (polygons && subdiv->polygonsOffset() != subdiv->polygonsEnd()) {
|
||||
quint32 start = _polygonsOffset + subdiv->polygonsOffset();
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user