diff --git a/src/map/IMG/gmap.cpp b/src/map/IMG/gmap.cpp index 22111d82..0641169a 100644 --- a/src/map/IMG/gmap.cpp +++ b/src/map/IMG/gmap.cpp @@ -74,19 +74,17 @@ bool GMAP::readXML(const QString &path, QString &dataDir, QString &typFile, return true; } -bool GMAP::loadTile(const QDir &dir, quint16 &id) +bool GMAP::loadTile(const QDir &dir, bool baseMap) { VectorTile *tile = new VectorTile(); - SubFile *file; QFileInfoList ml = dir.entryInfoList(QDir::Files); for (int i = 0; i < ml.size(); i++) { const QFileInfo &fi = ml.at(i); - if ((file = tile->addFile(fi.absoluteFilePath(), tileType(fi.suffix())))) - file->setId(id++); + tile->addFile(fi.absoluteFilePath(), tileType(fi.suffix())); } - if (!tile->init()) { + if (!tile->init(baseMap)) { qWarning("%s: Invalid map tile", qPrintable(dir.path())); delete tile; return false; @@ -118,12 +116,15 @@ GMAP::GMAP(const QString &fileName) : _fileName(fileName) QDir dataDir(baseDir.filePath(dataDirPath)); QFileInfoList ml = dataDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot); - quint16 id = 0; - QFileInfo baseMap(baseMapPath); + + QFileInfo baseMap(dataDir.filePath(baseMapPath)); + _baseMap = !baseMapPath.isEmpty() && baseMap.exists(); + for (int i = 0; i < ml.size(); i++) { const QFileInfo &fi = ml.at(i); - if (fi.isDir() && fi.baseName() != baseMap.baseName()) - loadTile(QDir(fi.absoluteFilePath()), id); + if (fi.isDir()) + loadTile(QDir(fi.absoluteFilePath()), + fi.absoluteFilePath() == baseMap.absoluteFilePath()); } if (baseDir.exists(typFilePath)) diff --git a/src/map/IMG/gmap.h b/src/map/IMG/gmap.h index ed46457a..b753f501 100644 --- a/src/map/IMG/gmap.h +++ b/src/map/IMG/gmap.h @@ -22,7 +22,7 @@ private: QString &typFile, QString &baseMap); void subProduct(QXmlStreamReader &reader, QString &dataDir, QString &baseMap); - bool loadTile(const QDir &dir, quint16 &id); + bool loadTile(const QDir &dir, bool baseMap); QString _fileName; }; diff --git a/src/map/IMG/img.cpp b/src/map/IMG/img.cpp index 371c52e8..f729bc95 100644 --- a/src/map/IMG/img.cpp +++ b/src/map/IMG/img.cpp @@ -136,7 +136,7 @@ IMG::IMG(const QString &fileName) : _file(fileName) it != tileMap.constEnd(); ++it) { VectorTile *tile = it.value(); - if (!tile->init()) { + if (!tile->init(false)) { qWarning("%s: %s: Invalid map tile", qPrintable(_file.fileName()), qPrintable(it.key())); delete tile; diff --git a/src/map/IMG/mapdata.cpp b/src/map/IMG/mapdata.cpp index 8d50a138..00fa621d 100644 --- a/src/map/IMG/mapdata.cpp +++ b/src/map/IMG/mapdata.cpp @@ -8,13 +8,15 @@ struct PolyCTX { - PolyCTX(const RectC &rect, int bits, QList *polygons, - QList *lines, QCache *polyCache) : rect(rect), bits(bits), polygons(polygons), + PolyCTX(const RectC &rect, int bits, bool baseMap, + QList *polygons, QList *lines, + QCache *polyCache) + : rect(rect), bits(bits), baseMap(baseMap), polygons(polygons), lines(lines), polyCache(polyCache) {} const RectC ▭ int bits; + bool baseMap; QList *polygons; QList *lines; QCache *polyCache; @@ -22,12 +24,15 @@ struct PolyCTX struct PointCTX { - PointCTX(const RectC &rect, int bits, QList *points, + PointCTX(const RectC &rect, int bits, bool baseMap, + QList *points, QCache > *pointCache) - : rect(rect), bits(bits), points(points), pointCache(pointCache) {} + : rect(rect), bits(bits), baseMap(baseMap), points(points), + pointCache(pointCache) {} const RectC ▭ int bits; + bool baseMap; QList *points; QCache > *pointCache; }; @@ -35,19 +40,21 @@ struct PointCTX inline bool polyCb(VectorTile *tile, void *context) { PolyCTX *ctx = (PolyCTX*)context; - tile->polys(ctx->rect, ctx->bits, ctx->polygons, ctx->lines, ctx->polyCache); + tile->polys(ctx->rect, ctx->bits, ctx->baseMap, ctx->polygons, ctx->lines, + ctx->polyCache); return true; } inline bool pointCb(VectorTile *tile, void *context) { PointCTX *ctx = (PointCTX*)context; - tile->points(ctx->rect, ctx->bits, ctx->points, ctx->pointCache); + tile->points(ctx->rect, ctx->bits, ctx->baseMap, ctx->points, + ctx->pointCache); return true; } -MapData::MapData() : _typ(0), _style(0), _valid(false) +MapData::MapData() : _typ(0), _style(0), _baseMap(false), _valid(false) { _polyCache.setMaxCost(CACHED_SUBDIVS_COUNT); _pointCache.setMaxCost(CACHED_SUBDIVS_COUNT); @@ -66,7 +73,7 @@ MapData::~MapData() void MapData::polys(const RectC &rect, int bits, QList *polygons, QList *lines) { - PolyCTX ctx(rect, bits, polygons, lines, &_polyCache); + PolyCTX ctx(rect, bits, _baseMap, polygons, lines, &_polyCache); double min[2], max[2]; min[0] = rect.left(); @@ -79,7 +86,7 @@ void MapData::polys(const RectC &rect, int bits, QList *polygons, void MapData::points(const RectC &rect, int bits, QList *points) { - PointCTX ctx(rect, bits, points, &_pointCache); + PointCTX ctx(rect, bits, _baseMap, points, &_pointCache); double min[2], max[2]; min[0] = rect.left(); diff --git a/src/map/IMG/mapdata.h b/src/map/IMG/mapdata.h index e998183d..423c24ec 100644 --- a/src/map/IMG/mapdata.h +++ b/src/map/IMG/mapdata.h @@ -79,6 +79,7 @@ protected: SubFile *_typ; Style *_style; TileTree _tileTree; + bool _baseMap; bool _valid; QString _errorString; diff --git a/src/map/IMG/rgnfile.cpp b/src/map/IMG/rgnfile.cpp index 71822863..6f8408c3 100644 --- a/src/map/IMG/rgnfile.cpp +++ b/src/map/IMG/rgnfile.cpp @@ -174,7 +174,7 @@ bool RGNFile::polyObjects(Handle &hdl, const SubDiv *subdiv, if (!(stream.atEnd() && stream.flush())) return false; - if (lbl && (labelPtr & 0x3FFFFF)) { + if (lbl && (labelPtr & 0x3FFFFF) && subdiv->bits() > 18) { if (labelPtr & 0x800000) { quint32 lblOff; if (net && net->lblOffset(netHdl, labelPtr & 0x3FFFFF, lblOff) @@ -281,7 +281,7 @@ bool RGNFile::extPolyObjects(Handle &hdl, const SubDiv *subdiv, quint32 shift, ? _linesFlags : _polygonsFlags, segmentType)) return false; - if (lbl && (labelPtr & 0x3FFFFF)) + if (lbl && (labelPtr & 0x3FFFFF) && subdiv->bits() > 18) poly.label = lbl->label(lblHdl, labelPtr & 0x3FFFFF); polys->append(poly); @@ -319,17 +319,18 @@ bool RGNFile::pointObjects(Handle &hdl, const SubDiv *subdiv, point.type = (quint16)type<<8 | subtype; - qint16 lonOffset = lon<<(24-subdiv->bits()); - qint16 latOffset = lat<<(24-subdiv->bits()); + qint32 lonOffset = lon<<(24-subdiv->bits()); + qint32 latOffset = lat<<(24-subdiv->bits()); point.coordinates = Coordinates(toWGS24(subdiv->lon() + lonOffset), toWGS24(subdiv->lat() + latOffset)); + uint hash = qHash(QPair(qHash(QPair + (subdiv->lon() + lonOffset, subdiv->lat() + latOffset)), + labelPtr & 0x3FFFFF)); + point.id = ((quint64)point.type)<<32 | hash; point.poi = labelPtr & 0x400000; - if (lbl && (labelPtr & 0x3FFFFF)) { + if (lbl && (labelPtr & 0x3FFFFF)) point.label = lbl->label(lblHdl, labelPtr & 0x3FFFFF, point.poi); - point.id = ((quint64)point.type)<<40 | ((quint64)lbl->id())<<24 - | (labelPtr & 0x3FFFFF); - } points->append(point); } @@ -360,8 +361,8 @@ bool RGNFile::extPointObjects(Handle &hdl, const SubDiv *subdiv, LBLFile *lbl, point.type = 0x10000 | (((quint32)type)<<8) | (subtype & 0x1F); - qint16 lonOffset = lon<<(24-subdiv->bits()); - qint16 latOffset = lat<<(24-subdiv->bits()); + qint32 lonOffset = lon<<(24-subdiv->bits()); + qint32 latOffset = lat<<(24-subdiv->bits()); point.coordinates = Coordinates(toWGS24(subdiv->lon() + lonOffset), toWGS24(subdiv->lat() + latOffset)); labelPtr = 0; @@ -378,12 +379,13 @@ bool RGNFile::extPointObjects(Handle &hdl, const SubDiv *subdiv, LBLFile *lbl, if (point.type == 0x11400) continue; + uint hash = qHash(QPair(qHash(QPair + (subdiv->lon() + lonOffset, subdiv->lat() + latOffset)), + labelPtr & 0x3FFFFF)); + point.id = ((quint64)point.type)<<32 | hash; point.poi = labelPtr & 0x400000; - if (lbl && (labelPtr & 0x3FFFFF)) { + if (lbl && (labelPtr & 0x3FFFFF)) point.label = lbl->label(lblHdl, labelPtr & 0x3FFFFF, point.poi); - point.id = ((quint64)point.type)<<40 - | ((quint64)lbl->id())<<24 | (labelPtr & 0x3FFFFF); - } points->append(point); } diff --git a/src/map/IMG/subfile.h b/src/map/IMG/subfile.h index 49688999..a339d2d9 100644 --- a/src/map/IMG/subfile.h +++ b/src/map/IMG/subfile.h @@ -42,12 +42,11 @@ public: }; SubFile(IMG *img) - : _gmpOffset(0), _img(img), _blocks(new QVector()), _path(0), - _id(0) {} + : _gmpOffset(0), _img(img), _blocks(new QVector()), _path(0) {} SubFile(SubFile *gmp, quint32 offset) : _gmpOffset(offset), _img(gmp->_img), - _blocks(gmp->_blocks), _path(gmp->_path), _id(gmp->id()) {} + _blocks(gmp->_blocks), _path(gmp->_path) {} SubFile(const QString &path) - : _gmpOffset(0), _img(0), _blocks(0), _path(new QString(path)), _id(0) {} + : _gmpOffset(0), _img(0), _blocks(0), _path(new QString(path)) {} ~SubFile() { if (!_gmpOffset) { @@ -57,7 +56,6 @@ public: } void addBlock(quint16 block) {_blocks->append(block);} - void setId(quint16 id) {_id = id;} bool seek(Handle &handle, quint32 pos) const; @@ -137,7 +135,6 @@ public: bool readVUInt32(Handle &hdl, quint32 &val) const; bool readVBitfield32(Handle &hdl, quint32 &bitfield) const; - quint16 id() const {return _blocks ? _blocks->first() : _id;} QString fileName() const {return _path ? *_path : _img->fileName();} protected: @@ -156,7 +153,6 @@ private: IMG *_img; QVector *_blocks; QString *_path; - quint16 _id; }; #endif // SUBFILE_H diff --git a/src/map/IMG/trefile.cpp b/src/map/IMG/trefile.cpp index 0bfd0cb7..43816070 100644 --- a/src/map/IMG/trefile.cpp +++ b/src/map/IMG/trefile.cpp @@ -37,7 +37,7 @@ TREFile::~TREFile() clear(); } -bool TREFile::init() +bool TREFile::init(bool baseMap) { Handle hdl(this); quint8 locked; @@ -108,6 +108,8 @@ bool TREFile::init() } } + _isBaseMap = baseMap; + return (_firstLevel >= 0); } @@ -236,10 +238,17 @@ void TREFile::clear() _subdivs.clear(); } -int TREFile::level(int bits) +int TREFile::level(int bits, bool baseMap) { int idx = _firstLevel; + if (baseMap) { + if (!_isBaseMap && _levels.at(idx).bits > bits) + return -1; + if (_isBaseMap && bits > _levels.last().bits) + return -1; + } + for (int i = idx + 1; i < _levels.size(); i++) { if (_levels.at(i).bits > bits) break; @@ -259,10 +268,10 @@ static bool cb(SubDiv *subdiv, void *context) return true; } -QList TREFile::subdivs(const RectC &rect, int bits) +QList TREFile::subdivs(const RectC &rect, int bits, bool baseMap) { QList list; - SubDivTree *tree = _subdivs.value(level(bits)); + SubDivTree *tree = _subdivs.value(level(bits, baseMap)); double min[2], max[2]; min[0] = rect.left(); diff --git a/src/map/IMG/trefile.h b/src/map/IMG/trefile.h index 6d16c003..d3869748 100644 --- a/src/map/IMG/trefile.h +++ b/src/map/IMG/trefile.h @@ -18,11 +18,11 @@ public: TREFile(SubFile *gmp, quint32 offset) : SubFile(gmp, offset) {} ~TREFile(); - bool init(); + bool init(bool baseMap); void clear(); const RectC &bounds() const {return _bounds;} - QList subdivs(const RectC &rect, int bits); + QList subdivs(const RectC &rect, int bits, bool baseMap); quint32 shift(quint8 bits) const {return (bits == _levels.last().bits) ? (_flags >> 0xb) & 7 : 0;} @@ -42,7 +42,7 @@ private: typedef RTree SubDivTree; bool load(int idx); - int level(int bits); + int level(int bits, bool baseMap); bool parsePoly(Handle hdl, quint32 pos, const QMap &level2bits, QMap &map); bool parsePoints(Handle hdl, quint32 pos, const QMap &level2bits); @@ -55,6 +55,7 @@ private: Extended _extended; int _firstLevel; quint32 _flags; + bool _isBaseMap; QMap _subdivs; }; diff --git a/src/map/IMG/vectortile.cpp b/src/map/IMG/vectortile.cpp index 64e8c2dc..2888789d 100644 --- a/src/map/IMG/vectortile.cpp +++ b/src/map/IMG/vectortile.cpp @@ -82,12 +82,12 @@ SubFile *VectorTile::addFile(const QString &path, SubFile::Type type) } } -bool VectorTile::init() +bool VectorTile::init(bool baseMap) { if (_gmp && !initGMP()) return false; - if (!(_tre && _tre->init() && _rgn)) + if (!(_tre && _tre->init(baseMap) && _rgn)) return false; return true; @@ -111,16 +111,16 @@ bool VectorTile::initGMP() return true; } -void VectorTile::polys(const RectC &rect, int bits, QList *polygons, - QList *lines, QCache *polyCache) - const +void VectorTile::polys(const RectC &rect, int bits, bool baseMap, + QList *polygons, QList *lines, + QCache *polyCache) const { SubFile::Handle rgnHdl(_rgn), lblHdl(_lbl), netHdl(_net); if (!_rgn->initialized() && !_rgn->init(rgnHdl)) return; - QList subdivs = _tre->subdivs(rect, bits); + QList subdivs = _tre->subdivs(rect, bits, baseMap); for (int i = 0; i < subdivs.size(); i++) { SubDiv *subdiv = subdivs.at(i); @@ -151,15 +151,16 @@ void VectorTile::polys(const RectC &rect, int bits, QList *polygons, } } -void VectorTile::points(const RectC &rect, int bits, QList *points, - QCache > *pointCache) const +void VectorTile::points(const RectC &rect, int bits, bool baseMap, + QList *points, QCache > *pointCache) const { SubFile::Handle rgnHdl(_rgn), lblHdl(_lbl); if (!_rgn->initialized() && !_rgn->init(rgnHdl)) return; - QList subdivs = _tre->subdivs(rect, bits); + QList subdivs = _tre->subdivs(rect, bits, baseMap); for (int i = 0; i < subdivs.size(); i++) { SubDiv *subdiv = subdivs.at(i); diff --git a/src/map/IMG/vectortile.h b/src/map/IMG/vectortile.h index 8ac84f4d..c446c5e0 100644 --- a/src/map/IMG/vectortile.h +++ b/src/map/IMG/vectortile.h @@ -1,7 +1,6 @@ #ifndef VECTORTILE_H #define VECTORTILE_H -#include "img.h" #include "trefile.h" #include "trefile.h" #include "rgnfile.h" @@ -16,7 +15,7 @@ public: delete _tre; delete _rgn; delete _lbl; delete _net; delete _gmp; } - bool init(); + bool init(bool baseMap); void clear() {_tre->clear();} const RectC &bounds() const {return _tre->bounds();} @@ -25,11 +24,12 @@ public: SubFile *addFile(IMG *img, SubFile::Type type); SubFile *addFile(const QString &path, SubFile::Type type); - void polys(const RectC &rect, int bits, QList *polygons, - QList *lines, QCache *polyCache) - const; - void points(const RectC &rect, int bits, QList *points, - QCache > *pointCache) const; + void polys(const RectC &rect, int bits, bool baseMap, + QList *polygons, QList *lines, + QCache *polyCache) const; + void points(const RectC &rect, int bits, bool baseMap, + QList *points, QCache > *pointCache) const; static bool isTileFile(SubFile::Type type) {