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:
parent
863aa3f542
commit
b4cc88446a
@ -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();
|
||||||
|
@ -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;
|
||||||
|
@ -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) {
|
||||||
|
@ -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
|
||||||
|
@ -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();
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user