1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-11-24 19:55:53 +01:00

Use the GMAP basemaps rather than discarding them

+ some minor point rendering issues fixes
This commit is contained in:
Martin Tůma 2020-02-11 21:03:55 +01:00
parent 2d5e11f001
commit 2d3ad41d69
11 changed files with 83 additions and 65 deletions

View File

@ -74,19 +74,17 @@ bool GMAP::readXML(const QString &path, QString &dataDir, QString &typFile,
return true; return true;
} }
bool GMAP::loadTile(const QDir &dir, quint16 &id) bool GMAP::loadTile(const QDir &dir, bool baseMap)
{ {
VectorTile *tile = new VectorTile(); VectorTile *tile = new VectorTile();
SubFile *file;
QFileInfoList ml = dir.entryInfoList(QDir::Files); QFileInfoList ml = dir.entryInfoList(QDir::Files);
for (int i = 0; i < ml.size(); i++) { for (int i = 0; i < ml.size(); i++) {
const QFileInfo &fi = ml.at(i); const QFileInfo &fi = ml.at(i);
if ((file = tile->addFile(fi.absoluteFilePath(), tileType(fi.suffix())))) tile->addFile(fi.absoluteFilePath(), tileType(fi.suffix()));
file->setId(id++);
} }
if (!tile->init()) { if (!tile->init(baseMap)) {
qWarning("%s: Invalid map tile", qPrintable(dir.path())); qWarning("%s: Invalid map tile", qPrintable(dir.path()));
delete tile; delete tile;
return false; return false;
@ -118,12 +116,15 @@ GMAP::GMAP(const QString &fileName) : _fileName(fileName)
QDir dataDir(baseDir.filePath(dataDirPath)); QDir dataDir(baseDir.filePath(dataDirPath));
QFileInfoList ml = dataDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot); 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++) { for (int i = 0; i < ml.size(); i++) {
const QFileInfo &fi = ml.at(i); const QFileInfo &fi = ml.at(i);
if (fi.isDir() && fi.baseName() != baseMap.baseName()) if (fi.isDir())
loadTile(QDir(fi.absoluteFilePath()), id); loadTile(QDir(fi.absoluteFilePath()),
fi.absoluteFilePath() == baseMap.absoluteFilePath());
} }
if (baseDir.exists(typFilePath)) if (baseDir.exists(typFilePath))

View File

@ -22,7 +22,7 @@ private:
QString &typFile, QString &baseMap); QString &typFile, QString &baseMap);
void subProduct(QXmlStreamReader &reader, QString &dataDir, void subProduct(QXmlStreamReader &reader, QString &dataDir,
QString &baseMap); QString &baseMap);
bool loadTile(const QDir &dir, quint16 &id); bool loadTile(const QDir &dir, bool baseMap);
QString _fileName; QString _fileName;
}; };

View File

@ -136,7 +136,7 @@ IMG::IMG(const QString &fileName) : _file(fileName)
it != tileMap.constEnd(); ++it) { it != tileMap.constEnd(); ++it) {
VectorTile *tile = it.value(); VectorTile *tile = it.value();
if (!tile->init()) { if (!tile->init(false)) {
qWarning("%s: %s: Invalid map tile", qPrintable(_file.fileName()), qWarning("%s: %s: Invalid map tile", qPrintable(_file.fileName()),
qPrintable(it.key())); qPrintable(it.key()));
delete tile; delete tile;

View File

@ -8,13 +8,15 @@
struct PolyCTX struct PolyCTX
{ {
PolyCTX(const RectC &rect, int bits, QList<MapData::Poly> *polygons, PolyCTX(const RectC &rect, int bits, bool baseMap,
QList<MapData::Poly> *lines, QCache<const SubDiv*, QList<MapData::Poly> *polygons, QList<MapData::Poly> *lines,
MapData::Polys> *polyCache) : rect(rect), bits(bits), polygons(polygons), QCache<const SubDiv*, MapData::Polys> *polyCache)
: rect(rect), bits(bits), baseMap(baseMap), polygons(polygons),
lines(lines), polyCache(polyCache) {} lines(lines), polyCache(polyCache) {}
const RectC &rect; const RectC &rect;
int bits; int bits;
bool baseMap;
QList<MapData::Poly> *polygons; QList<MapData::Poly> *polygons;
QList<MapData::Poly> *lines; QList<MapData::Poly> *lines;
QCache<const SubDiv*, MapData::Polys> *polyCache; QCache<const SubDiv*, MapData::Polys> *polyCache;
@ -22,12 +24,15 @@ struct PolyCTX
struct PointCTX struct PointCTX
{ {
PointCTX(const RectC &rect, int bits, QList<MapData::Point> *points, PointCTX(const RectC &rect, int bits, bool baseMap,
QList<MapData::Point> *points,
QCache<const SubDiv*, QList<MapData::Point> > *pointCache) QCache<const SubDiv*, QList<MapData::Point> > *pointCache)
: rect(rect), bits(bits), points(points), pointCache(pointCache) {} : rect(rect), bits(bits), baseMap(baseMap), points(points),
pointCache(pointCache) {}
const RectC &rect; const RectC &rect;
int bits; int bits;
bool baseMap;
QList<MapData::Point> *points; QList<MapData::Point> *points;
QCache<const SubDiv*, QList<MapData::Point> > *pointCache; QCache<const SubDiv*, QList<MapData::Point> > *pointCache;
}; };
@ -35,19 +40,21 @@ struct PointCTX
inline bool polyCb(VectorTile *tile, void *context) inline bool polyCb(VectorTile *tile, void *context)
{ {
PolyCTX *ctx = (PolyCTX*)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; return true;
} }
inline bool pointCb(VectorTile *tile, void *context) inline bool pointCb(VectorTile *tile, void *context)
{ {
PointCTX *ctx = (PointCTX*)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; 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); _polyCache.setMaxCost(CACHED_SUBDIVS_COUNT);
_pointCache.setMaxCost(CACHED_SUBDIVS_COUNT); _pointCache.setMaxCost(CACHED_SUBDIVS_COUNT);
@ -66,7 +73,7 @@ MapData::~MapData()
void MapData::polys(const RectC &rect, int bits, QList<Poly> *polygons, void MapData::polys(const RectC &rect, int bits, QList<Poly> *polygons,
QList<Poly> *lines) QList<Poly> *lines)
{ {
PolyCTX ctx(rect, bits, polygons, lines, &_polyCache); PolyCTX ctx(rect, bits, _baseMap, polygons, lines, &_polyCache);
double min[2], max[2]; double min[2], max[2];
min[0] = rect.left(); min[0] = rect.left();
@ -79,7 +86,7 @@ void MapData::polys(const RectC &rect, int bits, QList<Poly> *polygons,
void MapData::points(const RectC &rect, int bits, QList<Point> *points) void MapData::points(const RectC &rect, int bits, QList<Point> *points)
{ {
PointCTX ctx(rect, bits, points, &_pointCache); PointCTX ctx(rect, bits, _baseMap, points, &_pointCache);
double min[2], max[2]; double min[2], max[2];
min[0] = rect.left(); min[0] = rect.left();

View File

@ -79,6 +79,7 @@ protected:
SubFile *_typ; SubFile *_typ;
Style *_style; Style *_style;
TileTree _tileTree; TileTree _tileTree;
bool _baseMap;
bool _valid; bool _valid;
QString _errorString; QString _errorString;

View File

@ -174,7 +174,7 @@ bool RGNFile::polyObjects(Handle &hdl, const SubDiv *subdiv,
if (!(stream.atEnd() && stream.flush())) if (!(stream.atEnd() && stream.flush()))
return false; return false;
if (lbl && (labelPtr & 0x3FFFFF)) { if (lbl && (labelPtr & 0x3FFFFF) && subdiv->bits() > 18) {
if (labelPtr & 0x800000) { if (labelPtr & 0x800000) {
quint32 lblOff; quint32 lblOff;
if (net && net->lblOffset(netHdl, labelPtr & 0x3FFFFF, 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)) ? _linesFlags : _polygonsFlags, segmentType))
return false; return false;
if (lbl && (labelPtr & 0x3FFFFF)) if (lbl && (labelPtr & 0x3FFFFF) && subdiv->bits() > 18)
poly.label = lbl->label(lblHdl, labelPtr & 0x3FFFFF); poly.label = lbl->label(lblHdl, labelPtr & 0x3FFFFF);
polys->append(poly); polys->append(poly);
@ -319,17 +319,18 @@ bool RGNFile::pointObjects(Handle &hdl, const SubDiv *subdiv,
point.type = (quint16)type<<8 | subtype; point.type = (quint16)type<<8 | subtype;
qint16 lonOffset = lon<<(24-subdiv->bits()); qint32 lonOffset = lon<<(24-subdiv->bits());
qint16 latOffset = lat<<(24-subdiv->bits()); qint32 latOffset = lat<<(24-subdiv->bits());
point.coordinates = Coordinates(toWGS24(subdiv->lon() + lonOffset), point.coordinates = Coordinates(toWGS24(subdiv->lon() + lonOffset),
toWGS24(subdiv->lat() + latOffset)); toWGS24(subdiv->lat() + latOffset));
uint hash = qHash(QPair<uint,uint>(qHash(QPair<qint32, qint32>
(subdiv->lon() + lonOffset, subdiv->lat() + latOffset)),
labelPtr & 0x3FFFFF));
point.id = ((quint64)point.type)<<32 | hash;
point.poi = labelPtr & 0x400000; point.poi = labelPtr & 0x400000;
if (lbl && (labelPtr & 0x3FFFFF)) { if (lbl && (labelPtr & 0x3FFFFF))
point.label = lbl->label(lblHdl, labelPtr & 0x3FFFFF, point.poi); point.label = lbl->label(lblHdl, labelPtr & 0x3FFFFF, point.poi);
point.id = ((quint64)point.type)<<40 | ((quint64)lbl->id())<<24
| (labelPtr & 0x3FFFFF);
}
points->append(point); 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); point.type = 0x10000 | (((quint32)type)<<8) | (subtype & 0x1F);
qint16 lonOffset = lon<<(24-subdiv->bits()); qint32 lonOffset = lon<<(24-subdiv->bits());
qint16 latOffset = lat<<(24-subdiv->bits()); qint32 latOffset = lat<<(24-subdiv->bits());
point.coordinates = Coordinates(toWGS24(subdiv->lon() + lonOffset), point.coordinates = Coordinates(toWGS24(subdiv->lon() + lonOffset),
toWGS24(subdiv->lat() + latOffset)); toWGS24(subdiv->lat() + latOffset));
labelPtr = 0; labelPtr = 0;
@ -378,12 +379,13 @@ bool RGNFile::extPointObjects(Handle &hdl, const SubDiv *subdiv, LBLFile *lbl,
if (point.type == 0x11400) if (point.type == 0x11400)
continue; continue;
uint hash = qHash(QPair<uint,uint>(qHash(QPair<qint32, qint32>
(subdiv->lon() + lonOffset, subdiv->lat() + latOffset)),
labelPtr & 0x3FFFFF));
point.id = ((quint64)point.type)<<32 | hash;
point.poi = labelPtr & 0x400000; point.poi = labelPtr & 0x400000;
if (lbl && (labelPtr & 0x3FFFFF)) { if (lbl && (labelPtr & 0x3FFFFF))
point.label = lbl->label(lblHdl, labelPtr & 0x3FFFFF, point.poi); point.label = lbl->label(lblHdl, labelPtr & 0x3FFFFF, point.poi);
point.id = ((quint64)point.type)<<40
| ((quint64)lbl->id())<<24 | (labelPtr & 0x3FFFFF);
}
points->append(point); points->append(point);
} }

View File

@ -42,12 +42,11 @@ public:
}; };
SubFile(IMG *img) SubFile(IMG *img)
: _gmpOffset(0), _img(img), _blocks(new QVector<quint16>()), _path(0), : _gmpOffset(0), _img(img), _blocks(new QVector<quint16>()), _path(0) {}
_id(0) {}
SubFile(SubFile *gmp, quint32 offset) : _gmpOffset(offset), _img(gmp->_img), 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) 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() ~SubFile()
{ {
if (!_gmpOffset) { if (!_gmpOffset) {
@ -57,7 +56,6 @@ public:
} }
void addBlock(quint16 block) {_blocks->append(block);} void addBlock(quint16 block) {_blocks->append(block);}
void setId(quint16 id) {_id = id;}
bool seek(Handle &handle, quint32 pos) const; bool seek(Handle &handle, quint32 pos) const;
@ -137,7 +135,6 @@ public:
bool readVUInt32(Handle &hdl, quint32 &val) const; bool readVUInt32(Handle &hdl, quint32 &val) const;
bool readVBitfield32(Handle &hdl, quint32 &bitfield) const; bool readVBitfield32(Handle &hdl, quint32 &bitfield) const;
quint16 id() const {return _blocks ? _blocks->first() : _id;}
QString fileName() const {return _path ? *_path : _img->fileName();} QString fileName() const {return _path ? *_path : _img->fileName();}
protected: protected:
@ -156,7 +153,6 @@ private:
IMG *_img; IMG *_img;
QVector<quint16> *_blocks; QVector<quint16> *_blocks;
QString *_path; QString *_path;
quint16 _id;
}; };
#endif // SUBFILE_H #endif // SUBFILE_H

View File

@ -37,7 +37,7 @@ TREFile::~TREFile()
clear(); clear();
} }
bool TREFile::init() bool TREFile::init(bool baseMap)
{ {
Handle hdl(this); Handle hdl(this);
quint8 locked; quint8 locked;
@ -108,6 +108,8 @@ bool TREFile::init()
} }
} }
_isBaseMap = baseMap;
return (_firstLevel >= 0); return (_firstLevel >= 0);
} }
@ -236,10 +238,17 @@ void TREFile::clear()
_subdivs.clear(); _subdivs.clear();
} }
int TREFile::level(int bits) int TREFile::level(int bits, bool baseMap)
{ {
int idx = _firstLevel; 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++) { for (int i = idx + 1; i < _levels.size(); i++) {
if (_levels.at(i).bits > bits) if (_levels.at(i).bits > bits)
break; break;
@ -259,10 +268,10 @@ static bool cb(SubDiv *subdiv, void *context)
return true; return true;
} }
QList<SubDiv*> TREFile::subdivs(const RectC &rect, int bits) QList<SubDiv*> TREFile::subdivs(const RectC &rect, int bits, bool baseMap)
{ {
QList<SubDiv*> list; QList<SubDiv*> list;
SubDivTree *tree = _subdivs.value(level(bits)); SubDivTree *tree = _subdivs.value(level(bits, baseMap));
double min[2], max[2]; double min[2], max[2];
min[0] = rect.left(); min[0] = rect.left();

View File

@ -18,11 +18,11 @@ public:
TREFile(SubFile *gmp, quint32 offset) : SubFile(gmp, offset) {} TREFile(SubFile *gmp, quint32 offset) : SubFile(gmp, offset) {}
~TREFile(); ~TREFile();
bool init(); bool init(bool baseMap);
void clear(); void clear();
const RectC &bounds() const {return _bounds;} const RectC &bounds() const {return _bounds;}
QList<SubDiv*> subdivs(const RectC &rect, int bits); QList<SubDiv*> subdivs(const RectC &rect, int bits, bool baseMap);
quint32 shift(quint8 bits) const quint32 shift(quint8 bits) const
{return (bits == _levels.last().bits) ? (_flags >> 0xb) & 7 : 0;} {return (bits == _levels.last().bits) ? (_flags >> 0xb) & 7 : 0;}
@ -42,7 +42,7 @@ private:
typedef RTree<SubDiv*, double, 2> SubDivTree; typedef RTree<SubDiv*, double, 2> SubDivTree;
bool load(int idx); bool load(int idx);
int level(int bits); int level(int bits, bool baseMap);
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);
@ -55,6 +55,7 @@ private:
Extended _extended; Extended _extended;
int _firstLevel; int _firstLevel;
quint32 _flags; quint32 _flags;
bool _isBaseMap;
QMap<int, SubDivTree*> _subdivs; QMap<int, SubDivTree*> _subdivs;
}; };

View File

@ -82,12 +82,12 @@ SubFile *VectorTile::addFile(const QString &path, SubFile::Type type)
} }
} }
bool VectorTile::init() bool VectorTile::init(bool baseMap)
{ {
if (_gmp && !initGMP()) if (_gmp && !initGMP())
return false; return false;
if (!(_tre && _tre->init() && _rgn)) if (!(_tre && _tre->init(baseMap) && _rgn))
return false; return false;
return true; return true;
@ -111,16 +111,16 @@ bool VectorTile::initGMP()
return true; return true;
} }
void VectorTile::polys(const RectC &rect, int bits, QList<IMG::Poly> *polygons, void VectorTile::polys(const RectC &rect, int bits, bool baseMap,
QList<IMG::Poly> *lines, QCache<const SubDiv *, IMG::Polys> *polyCache) QList<IMG::Poly> *polygons, QList<IMG::Poly> *lines,
const QCache<const SubDiv *, IMG::Polys> *polyCache) const
{ {
SubFile::Handle rgnHdl(_rgn), lblHdl(_lbl), netHdl(_net); SubFile::Handle rgnHdl(_rgn), lblHdl(_lbl), netHdl(_net);
if (!_rgn->initialized() && !_rgn->init(rgnHdl)) if (!_rgn->initialized() && !_rgn->init(rgnHdl))
return; return;
QList<SubDiv*> subdivs = _tre->subdivs(rect, bits); QList<SubDiv*> subdivs = _tre->subdivs(rect, bits, baseMap);
for (int i = 0; i < subdivs.size(); i++) { for (int i = 0; i < subdivs.size(); i++) {
SubDiv *subdiv = subdivs.at(i); SubDiv *subdiv = subdivs.at(i);
@ -151,15 +151,16 @@ void VectorTile::polys(const RectC &rect, int bits, QList<IMG::Poly> *polygons,
} }
} }
void VectorTile::points(const RectC &rect, int bits, QList<IMG::Point> *points, void VectorTile::points(const RectC &rect, int bits, bool baseMap,
QCache<const SubDiv *, QList<IMG::Point> > *pointCache) const QList<IMG::Point> *points, QCache<const SubDiv *,
QList<IMG::Point> > *pointCache) const
{ {
SubFile::Handle rgnHdl(_rgn), lblHdl(_lbl); SubFile::Handle rgnHdl(_rgn), lblHdl(_lbl);
if (!_rgn->initialized() && !_rgn->init(rgnHdl)) if (!_rgn->initialized() && !_rgn->init(rgnHdl))
return; return;
QList<SubDiv*> subdivs = _tre->subdivs(rect, bits); QList<SubDiv*> subdivs = _tre->subdivs(rect, bits, baseMap);
for (int i = 0; i < subdivs.size(); i++) { for (int i = 0; i < subdivs.size(); i++) {
SubDiv *subdiv = subdivs.at(i); SubDiv *subdiv = subdivs.at(i);

View File

@ -1,7 +1,6 @@
#ifndef VECTORTILE_H #ifndef VECTORTILE_H
#define VECTORTILE_H #define VECTORTILE_H
#include "img.h"
#include "trefile.h" #include "trefile.h"
#include "trefile.h" #include "trefile.h"
#include "rgnfile.h" #include "rgnfile.h"
@ -16,7 +15,7 @@ public:
delete _tre; delete _rgn; delete _lbl; delete _net; delete _gmp; delete _tre; delete _rgn; delete _lbl; delete _net; delete _gmp;
} }
bool init(); bool init(bool baseMap);
void clear() {_tre->clear();} void clear() {_tre->clear();}
const RectC &bounds() const {return _tre->bounds();} const RectC &bounds() const {return _tre->bounds();}
@ -25,11 +24,12 @@ public:
SubFile *addFile(IMG *img, SubFile::Type type); SubFile *addFile(IMG *img, SubFile::Type type);
SubFile *addFile(const QString &path, SubFile::Type type); SubFile *addFile(const QString &path, SubFile::Type type);
void polys(const RectC &rect, int bits, QList<IMG::Poly> *polygons, void polys(const RectC &rect, int bits, bool baseMap,
QList<IMG::Poly> *lines, QCache<const SubDiv *, IMG::Polys> *polyCache) QList<IMG::Poly> *polygons, QList<IMG::Poly> *lines,
const; QCache<const SubDiv *, IMG::Polys> *polyCache) const;
void points(const RectC &rect, int bits, QList<IMG::Point> *points, void points(const RectC &rect, int bits, bool baseMap,
QCache<const SubDiv*, QList<IMG::Point> > *pointCache) const; QList<IMG::Point> *points, QCache<const SubDiv*,
QList<IMG::Point> > *pointCache) const;
static bool isTileFile(SubFile::Type type) static bool isTileFile(SubFile::Type type)
{ {