mirror of
https://github.com/tumic0/GPXSee.git
synced 2024-11-24 11:45:53 +01:00
Fixed broken handling of IMG "multi-maps" (maps with overviews)
This commit is contained in:
parent
108444d29b
commit
f026387d76
@ -124,6 +124,7 @@ HEADERS += src/common/config.h \
|
|||||||
src/map/ENC/rastertile.h \
|
src/map/ENC/rastertile.h \
|
||||||
src/map/ENC/style.h \
|
src/map/ENC/style.h \
|
||||||
src/map/IMG/section.h \
|
src/map/IMG/section.h \
|
||||||
|
src/map/IMG/zoom.h \
|
||||||
src/map/encmap.h \
|
src/map/encmap.h \
|
||||||
src/map/ENC/iso8211.h \
|
src/map/ENC/iso8211.h \
|
||||||
src/map/gemfmap.h \
|
src/map/gemfmap.h \
|
||||||
|
@ -23,21 +23,18 @@ static SubFile::Type tileType(const QString &suffix)
|
|||||||
return SubFile::Unknown;
|
return SubFile::Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMAPData::subProduct(QXmlStreamReader &reader, QString &dataDir,
|
void GMAPData::subProduct(QXmlStreamReader &reader, QString &dataDir)
|
||||||
QString &baseMap)
|
|
||||||
{
|
{
|
||||||
while (reader.readNextStartElement()) {
|
while (reader.readNextStartElement()) {
|
||||||
if (reader.name() == QLatin1String("Directory"))
|
if (reader.name() == QLatin1String("Directory"))
|
||||||
dataDir = reader.readElementText();
|
dataDir = reader.readElementText();
|
||||||
else if (reader.name() == QLatin1String("BaseMap"))
|
|
||||||
baseMap = reader.readElementText();
|
|
||||||
else
|
else
|
||||||
reader.skipCurrentElement();
|
reader.skipCurrentElement();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMAPData::mapProduct(QXmlStreamReader &reader, QString &dataDir,
|
void GMAPData::mapProduct(QXmlStreamReader &reader, QString &dataDir,
|
||||||
QString &typFile, QString &baseMap)
|
QString &typFile)
|
||||||
{
|
{
|
||||||
while (reader.readNextStartElement()) {
|
while (reader.readNextStartElement()) {
|
||||||
if (reader.name() == QLatin1String("Name"))
|
if (reader.name() == QLatin1String("Name"))
|
||||||
@ -45,14 +42,13 @@ void GMAPData::mapProduct(QXmlStreamReader &reader, QString &dataDir,
|
|||||||
else if (reader.name() == QLatin1String("TYP"))
|
else if (reader.name() == QLatin1String("TYP"))
|
||||||
typFile = reader.readElementText();
|
typFile = reader.readElementText();
|
||||||
else if (reader.name() == QLatin1String("SubProduct"))
|
else if (reader.name() == QLatin1String("SubProduct"))
|
||||||
subProduct(reader, dataDir, baseMap);
|
subProduct(reader, dataDir);
|
||||||
else
|
else
|
||||||
reader.skipCurrentElement();
|
reader.skipCurrentElement();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GMAPData::readXML(const QString &path, QString &dataDir, QString &typFile,
|
bool GMAPData::readXML(const QString &path, QString &dataDir, QString &typFile)
|
||||||
QString &baseMap)
|
|
||||||
{
|
{
|
||||||
QFile file(path);
|
QFile file(path);
|
||||||
|
|
||||||
@ -62,7 +58,7 @@ bool GMAPData::readXML(const QString &path, QString &dataDir, QString &typFile,
|
|||||||
QXmlStreamReader reader(&file);
|
QXmlStreamReader reader(&file);
|
||||||
if (reader.readNextStartElement()) {
|
if (reader.readNextStartElement()) {
|
||||||
if (reader.name() == QLatin1String("MapProduct"))
|
if (reader.name() == QLatin1String("MapProduct"))
|
||||||
mapProduct(reader, dataDir, typFile, baseMap);
|
mapProduct(reader, dataDir, typFile);
|
||||||
else
|
else
|
||||||
reader.raiseError("Not a GMAP XML file");
|
reader.raiseError("Not a GMAP XML file");
|
||||||
}
|
}
|
||||||
@ -75,7 +71,7 @@ bool GMAPData::readXML(const QString &path, QString &dataDir, QString &typFile,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GMAPData::loadTile(const QDir &dir, bool baseMap)
|
bool GMAPData::loadTile(const QDir &dir)
|
||||||
{
|
{
|
||||||
VectorTile *tile = new VectorTile();
|
VectorTile *tile = new VectorTile();
|
||||||
|
|
||||||
@ -103,19 +99,14 @@ bool GMAPData::loadTile(const QDir &dir, bool baseMap)
|
|||||||
_tileTree.Insert(min, max, tile);
|
_tileTree.Insert(min, max, tile);
|
||||||
|
|
||||||
_bounds |= tile->bounds();
|
_bounds |= tile->bounds();
|
||||||
if (tile->zooms().min() < _zooms.min())
|
|
||||||
_zooms.setMin(tile->zooms().min());
|
|
||||||
|
|
||||||
if (baseMap)
|
|
||||||
_baseMap = tile->zooms();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
GMAPData::GMAPData(const QString &fileName) : MapData(fileName)
|
GMAPData::GMAPData(const QString &fileName) : MapData(fileName)
|
||||||
{
|
{
|
||||||
QString dataDirPath, typFilePath, baseMapPath;
|
QString dataDirPath, typFilePath;
|
||||||
if (!readXML(fileName, dataDirPath, typFilePath, baseMapPath))
|
if (!readXML(fileName, dataDirPath, typFilePath))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QDir baseDir(QFileInfo(fileName).absoluteDir());
|
QDir baseDir(QFileInfo(fileName).absoluteDir());
|
||||||
@ -125,13 +116,11 @@ GMAPData::GMAPData(const QString &fileName) : MapData(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);
|
||||||
QFileInfo baseMap(dataDir.filePath(baseMapPath));
|
|
||||||
|
|
||||||
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())
|
if (fi.isDir())
|
||||||
loadTile(QDir(fi.absoluteFilePath()),
|
loadTile(QDir(fi.absoluteFilePath()));
|
||||||
fi.absoluteFilePath() == baseMap.absoluteFilePath());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (baseDir.exists(typFilePath)) {
|
if (baseDir.exists(typFilePath)) {
|
||||||
@ -143,6 +132,8 @@ GMAPData::GMAPData(const QString &fileName) : MapData(fileName)
|
|||||||
_errorString = "No usable map tile found";
|
_errorString = "No usable map tile found";
|
||||||
else
|
else
|
||||||
_valid = true;
|
_valid = true;
|
||||||
|
|
||||||
|
computeZooms();
|
||||||
}
|
}
|
||||||
|
|
||||||
GMAPData::~GMAPData()
|
GMAPData::~GMAPData()
|
||||||
|
@ -15,13 +15,10 @@ public:
|
|||||||
~GMAPData();
|
~GMAPData();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool readXML(const QString &path, QString &dataDir, QString &typFile,
|
bool readXML(const QString &path, QString &dataDir, QString &typFile);
|
||||||
QString &baseMap);
|
void mapProduct(QXmlStreamReader &reader, QString &dataDir, QString &typFile);
|
||||||
void mapProduct(QXmlStreamReader &reader, QString &dataDir,
|
void subProduct(QXmlStreamReader &reader, QString &dataDir);
|
||||||
QString &typFile, QString &baseMap);
|
bool loadTile(const QDir &dir);
|
||||||
void subProduct(QXmlStreamReader &reader, QString &dataDir,
|
|
||||||
QString &baseMap);
|
|
||||||
bool loadTile(const QDir &dir, bool baseMap);
|
|
||||||
|
|
||||||
QList<const QString*> _files;
|
QList<const QString*> _files;
|
||||||
};
|
};
|
||||||
|
@ -156,32 +156,6 @@ bool IMGData::createTileTree(const TileMap &tileMap)
|
|||||||
_tileTree.Insert(min, max, tile);
|
_tileTree.Insert(min, max, tile);
|
||||||
|
|
||||||
_bounds |= tile->bounds();
|
_bounds |= tile->bounds();
|
||||||
if (tile->zooms().min() < _zooms.min())
|
|
||||||
_zooms.setMin(tile->zooms().min());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Detect and mark basemap
|
|
||||||
TileTree::Iterator it;
|
|
||||||
bool baseMap = false;
|
|
||||||
|
|
||||||
for (_tileTree.GetFirst(it); !_tileTree.IsNull(it); _tileTree.GetNext(it)) {
|
|
||||||
VectorTile *tile = _tileTree.GetAt(it);
|
|
||||||
if (tile->zooms().min() > _zooms.min()) {
|
|
||||||
baseMap = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (baseMap) {
|
|
||||||
for (_tileTree.GetFirst(it); !_tileTree.IsNull(it);
|
|
||||||
_tileTree.GetNext(it)) {
|
|
||||||
VectorTile *tile = _tileTree.GetAt(it);
|
|
||||||
if (tile->zooms().min() == _zooms.min())
|
|
||||||
_baseMap = tile->zooms();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* Allow some extra zoom out on maps without basemaps, but not too much
|
|
||||||
as this would kill the rendering performance. */
|
|
||||||
_zooms.setMin(_zooms.min() - 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (_tileTree.Count() > 0);
|
return (_tileTree.Count() > 0);
|
||||||
@ -209,6 +183,8 @@ IMGData::IMGData(const QString &fileName) : MapData(fileName)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
computeZooms();
|
||||||
|
|
||||||
_valid = true;
|
_valid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ using namespace IMG;
|
|||||||
bool MapData::polyCb(VectorTile *tile, void *context)
|
bool MapData::polyCb(VectorTile *tile, void *context)
|
||||||
{
|
{
|
||||||
PolyCTX *ctx = (PolyCTX*)context;
|
PolyCTX *ctx = (PolyCTX*)context;
|
||||||
tile->polys(ctx->rect, ctx->bits, ctx->baseMap, ctx->polygons, ctx->lines,
|
tile->polys(ctx->rect, ctx->zoom, ctx->polygons, ctx->lines,
|
||||||
ctx->polyCache);
|
ctx->polyCache);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -19,14 +19,13 @@ bool MapData::polyCb(VectorTile *tile, void *context)
|
|||||||
bool MapData::pointCb(VectorTile *tile, void *context)
|
bool MapData::pointCb(VectorTile *tile, void *context)
|
||||||
{
|
{
|
||||||
PointCTX *ctx = (PointCTX*)context;
|
PointCTX *ctx = (PointCTX*)context;
|
||||||
tile->points(ctx->rect, ctx->bits, ctx->baseMap, ctx->points,
|
tile->points(ctx->rect, ctx->zoom, ctx->points, ctx->pointCache);
|
||||||
ctx->pointCache);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MapData::MapData(const QString &fileName)
|
MapData::MapData(const QString &fileName)
|
||||||
: _fileName(fileName), _typ(0), _style(0), _zooms(24, 28), _valid(false)
|
: _fileName(fileName), _typ(0), _style(0), _valid(false)
|
||||||
{
|
{
|
||||||
_polyCache.setMaxCost(CACHED_SUBDIVS_COUNT);
|
_polyCache.setMaxCost(CACHED_SUBDIVS_COUNT);
|
||||||
_pointCache.setMaxCost(CACHED_SUBDIVS_COUNT);
|
_pointCache.setMaxCost(CACHED_SUBDIVS_COUNT);
|
||||||
@ -45,7 +44,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, _baseMap, polygons, lines, &_polyCache);
|
PolyCTX ctx(rect, zoom(bits), polygons, lines, &_polyCache);
|
||||||
double min[2], max[2];
|
double min[2], max[2];
|
||||||
|
|
||||||
min[0] = rect.left();
|
min[0] = rect.left();
|
||||||
@ -58,7 +57,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, _baseMap, points, &_pointCache);
|
PointCTX ctx(rect, zoom(bits), points, &_pointCache);
|
||||||
double min[2], max[2];
|
double min[2], max[2];
|
||||||
|
|
||||||
min[0] = rect.left();
|
min[0] = rect.left();
|
||||||
@ -97,3 +96,41 @@ void MapData::clear()
|
|||||||
_polyCache.clear();
|
_polyCache.clear();
|
||||||
_pointCache.clear();
|
_pointCache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MapData::computeZooms()
|
||||||
|
{
|
||||||
|
TileTree::Iterator it;
|
||||||
|
QSet<Zoom> zooms;
|
||||||
|
|
||||||
|
for (_tileTree.GetFirst(it); !_tileTree.IsNull(it); _tileTree.GetNext(it)) {
|
||||||
|
const QVector<Zoom> &z = _tileTree.GetAt(it)->zooms();
|
||||||
|
for (int i = 0; i < z.size(); i++)
|
||||||
|
zooms.insert(z.at(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
_zooms = zooms.values();
|
||||||
|
std::sort(_zooms.begin(), _zooms.end());
|
||||||
|
|
||||||
|
bool baseMap = false;
|
||||||
|
for (int i = 1; i < _zooms.size(); i++) {
|
||||||
|
if (_zooms.at(i).level() > _zooms.at(i-1).level()) {
|
||||||
|
baseMap = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_zoomLevels = Range(baseMap ? _zooms.first().bits()
|
||||||
|
: qMax(0, _zooms.first().bits() - 2), 28);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Zoom &MapData::zoom(int bits) const
|
||||||
|
{
|
||||||
|
int id = 0;
|
||||||
|
|
||||||
|
for (int i = 1; i < _zooms.size(); i++) {
|
||||||
|
if (_zooms.at(i).bits() > bits)
|
||||||
|
break;
|
||||||
|
id++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _zooms.at(id);
|
||||||
|
}
|
||||||
|
@ -8,9 +8,10 @@
|
|||||||
#include "common/rectc.h"
|
#include "common/rectc.h"
|
||||||
#include "common/rtree.h"
|
#include "common/rtree.h"
|
||||||
#include "common/range.h"
|
#include "common/range.h"
|
||||||
|
#include "common/hash.h"
|
||||||
#include "label.h"
|
#include "label.h"
|
||||||
#include "raster.h"
|
#include "raster.h"
|
||||||
|
#include "zoom.h"
|
||||||
|
|
||||||
namespace IMG {
|
namespace IMG {
|
||||||
|
|
||||||
@ -55,7 +56,7 @@ public:
|
|||||||
|
|
||||||
const QString &name() const {return _name;}
|
const QString &name() const {return _name;}
|
||||||
const RectC &bounds() const {return _bounds;}
|
const RectC &bounds() const {return _bounds;}
|
||||||
const Range &zooms() const {return _zooms;}
|
const Range &zooms() const {return _zoomLevels;}
|
||||||
const Style *style() const {return _style;}
|
const Style *style() const {return _style;}
|
||||||
void polys(const RectC &rect, int bits, QList<Poly> *polygons,
|
void polys(const RectC &rect, int bits, QList<Poly> *polygons,
|
||||||
QList<Poly> *lines);
|
QList<Poly> *lines);
|
||||||
@ -72,14 +73,16 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
typedef RTree<VectorTile*, double, 2> TileTree;
|
typedef RTree<VectorTile*, double, 2> TileTree;
|
||||||
|
|
||||||
|
void computeZooms();
|
||||||
|
|
||||||
QString _fileName;
|
QString _fileName;
|
||||||
QString _name;
|
QString _name;
|
||||||
RectC _bounds;
|
RectC _bounds;
|
||||||
SubFile *_typ;
|
SubFile *_typ;
|
||||||
Style *_style;
|
Style *_style;
|
||||||
TileTree _tileTree;
|
TileTree _tileTree;
|
||||||
Range _zooms;
|
QList<Zoom> _zooms;
|
||||||
Range _baseMap;
|
Range _zoomLevels;
|
||||||
|
|
||||||
bool _valid;
|
bool _valid;
|
||||||
QString _errorString;
|
QString _errorString;
|
||||||
@ -96,15 +99,14 @@ private:
|
|||||||
|
|
||||||
struct PolyCTX
|
struct PolyCTX
|
||||||
{
|
{
|
||||||
PolyCTX(const RectC &rect, int bits, const Range &baseMap,
|
PolyCTX(const RectC &rect, const Zoom &zoom,
|
||||||
QList<MapData::Poly> *polygons, QList<MapData::Poly> *lines,
|
QList<MapData::Poly> *polygons, QList<MapData::Poly> *lines,
|
||||||
QCache<const SubDiv*, MapData::Polys> *polyCache)
|
QCache<const SubDiv*, MapData::Polys> *polyCache)
|
||||||
: rect(rect), bits(bits), baseMap(baseMap), polygons(polygons),
|
: rect(rect), zoom(zoom), polygons(polygons), lines(lines),
|
||||||
lines(lines), polyCache(polyCache) {}
|
polyCache(polyCache) {}
|
||||||
|
|
||||||
const RectC ▭
|
const RectC ▭
|
||||||
int bits;
|
const Zoom &zoom;
|
||||||
const Range &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;
|
||||||
@ -112,19 +114,19 @@ private:
|
|||||||
|
|
||||||
struct PointCTX
|
struct PointCTX
|
||||||
{
|
{
|
||||||
PointCTX(const RectC &rect, int bits, const Range &baseMap,
|
PointCTX(const RectC &rect, const Zoom &zoom,
|
||||||
QList<MapData::Point> *points,
|
QList<MapData::Point> *points,
|
||||||
QCache<const SubDiv*, QList<MapData::Point> > *pointCache)
|
QCache<const SubDiv*, QList<MapData::Point> > *pointCache)
|
||||||
: rect(rect), bits(bits), baseMap(baseMap), points(points),
|
: rect(rect), zoom(zoom), points(points), pointCache(pointCache) {}
|
||||||
pointCache(pointCache) {}
|
|
||||||
|
|
||||||
const RectC ▭
|
const RectC ▭
|
||||||
int bits;
|
const Zoom &zoom;
|
||||||
const Range &baseMap;
|
|
||||||
QList<MapData::Point> *points;
|
QList<MapData::Point> *points;
|
||||||
QCache<const SubDiv*, QList<MapData::Point> > *pointCache;
|
QCache<const SubDiv*, QList<MapData::Point> > *pointCache;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const Zoom &zoom(int bits) const;
|
||||||
|
|
||||||
static bool polyCb(VectorTile *tile, void *context);
|
static bool polyCb(VectorTile *tile, void *context);
|
||||||
static bool pointCb(VectorTile *tile, void *context);
|
static bool pointCb(VectorTile *tile, void *context);
|
||||||
|
|
||||||
@ -132,7 +134,6 @@ private:
|
|||||||
QCache<const SubDiv*, QList<Point> > _pointCache;
|
QCache<const SubDiv*, QList<Point> > _pointCache;
|
||||||
|
|
||||||
friend class VectorTile;
|
friend class VectorTile;
|
||||||
friend struct PolyCTX;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -162,7 +162,7 @@ bool TREFile::load(int idx)
|
|||||||
SubDivTree *tree = new SubDivTree();
|
SubDivTree *tree = new SubDivTree();
|
||||||
const MapLevel &level = _levels.at(idx);
|
const MapLevel &level = _levels.at(idx);
|
||||||
|
|
||||||
_subdivs.insert(level.bits, tree);
|
_subdivs.insert(level.level, tree);
|
||||||
|
|
||||||
quint32 skip = 0;
|
quint32 skip = 0;
|
||||||
for (int i = 0; i < idx; i++)
|
for (int i = 0; i < idx; i++)
|
||||||
@ -282,27 +282,24 @@ void TREFile::clear()
|
|||||||
_subdivs.clear();
|
_subdivs.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
int TREFile::level(int bits, const Range &baseMap)
|
const TREFile::SubDivTree *TREFile::subdivs(const Zoom &zoom)
|
||||||
{
|
{
|
||||||
if (!baseMap.isNull()) {
|
int idx = -1;
|
||||||
if (zooms() != baseMap && bits <= baseMap.max())
|
|
||||||
return -1;
|
|
||||||
if (zooms() == baseMap && bits > baseMap.max())
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int idx = _firstLevel;
|
for (int i = _firstLevel; i < _levels.size(); i++) {
|
||||||
|
if (_levels.at(i).level == zoom.level()
|
||||||
for (int i = idx + 1; i < _levels.size(); i++) {
|
&& _levels.at(i).bits == zoom.bits()) {
|
||||||
if (_levels.at(i).bits > bits)
|
idx = i;
|
||||||
break;
|
break;
|
||||||
idx++;
|
}
|
||||||
}
|
}
|
||||||
|
if (idx < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (!_subdivs.contains(_levels.at(idx).bits) && !load(idx))
|
if (!_subdivs.contains(_levels.at(idx).level) && !load(idx))
|
||||||
return -1;
|
return 0;
|
||||||
|
|
||||||
return _levels.at(idx).bits;
|
return _subdivs.value(_levels.at(idx).level);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool cb(SubDiv *subdiv, void *context)
|
static bool cb(SubDiv *subdiv, void *context)
|
||||||
@ -312,11 +309,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, const Zoom &zoom)
|
||||||
const Range &baseMap)
|
|
||||||
{
|
{
|
||||||
QList<SubDiv*> list;
|
QList<SubDiv*> list;
|
||||||
SubDivTree *tree = _subdivs.value(level(bits, baseMap));
|
const SubDivTree *tree = subdivs(zoom);
|
||||||
double min[2], max[2];
|
double min[2], max[2];
|
||||||
|
|
||||||
min[0] = rect.left();
|
min[0] = rect.left();
|
||||||
@ -329,3 +325,13 @@ QList<SubDiv*> TREFile::subdivs(const RectC &rect, int bits,
|
|||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVector<Zoom> TREFile::zooms() const
|
||||||
|
{
|
||||||
|
QVector<Zoom> ret;
|
||||||
|
|
||||||
|
for (int i = _firstLevel; i < _levels.size(); i++)
|
||||||
|
ret.append(Zoom(_levels.at(i).level, _levels.at(i).bits));
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
@ -28,11 +28,10 @@ public:
|
|||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
const RectC &bounds() const {return _bounds;}
|
const RectC &bounds() const {return _bounds;}
|
||||||
QList<SubDiv*> subdivs(const RectC &rect, int bits, const Range &baseMap);
|
QList<SubDiv*> subdivs(const RectC &rect, const Zoom &zoom);
|
||||||
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;}
|
||||||
Range zooms() const
|
QVector<Zoom> zooms() const;
|
||||||
{return Range(_levels.at(_firstLevel).bits, _levels.last().bits);}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct MapLevel {
|
struct MapLevel {
|
||||||
@ -43,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, const Range &baseMap);
|
const SubDivTree *subdivs(const Zoom &zoom);
|
||||||
int readExtEntry(Handle &hdl, quint32 &polygons, quint32 &lines,
|
int readExtEntry(Handle &hdl, quint32 &polygons, quint32 &lines,
|
||||||
quint32 &points);
|
quint32 &points);
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ void VectorTile::clear()
|
|||||||
_loaded = 0;
|
_loaded = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VectorTile::polys(const RectC &rect, int bits, const Range &baseMap,
|
void VectorTile::polys(const RectC &rect, const Zoom &zoom,
|
||||||
QList<MapData::Poly> *polygons, QList<MapData::Poly> *lines,
|
QList<MapData::Poly> *polygons, QList<MapData::Poly> *lines,
|
||||||
QCache<const SubDiv *, MapData::Polys> *polyCache)
|
QCache<const SubDiv *, MapData::Polys> *polyCache)
|
||||||
{
|
{
|
||||||
@ -121,7 +121,7 @@ void VectorTile::polys(const RectC &rect, int bits, const Range &baseMap,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<SubDiv*> subdivs = _tre->subdivs(rect, bits, baseMap);
|
QList<SubDiv*> subdivs = _tre->subdivs(rect, zoom);
|
||||||
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);
|
||||||
|
|
||||||
@ -169,7 +169,7 @@ void VectorTile::polys(const RectC &rect, int bits, const Range &baseMap,
|
|||||||
delete rgnHdl; delete lblHdl; delete netHdl; delete nodHdl; delete nodHdl2;
|
delete rgnHdl; delete lblHdl; delete netHdl; delete nodHdl; delete nodHdl2;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VectorTile::points(const RectC &rect, int bits, const Range &baseMap,
|
void VectorTile::points(const RectC &rect, const Zoom &zoom,
|
||||||
QList<MapData::Point> *points, QCache<const SubDiv *,
|
QList<MapData::Point> *points, QCache<const SubDiv *,
|
||||||
QList<MapData::Point> > *pointCache)
|
QList<MapData::Point> > *pointCache)
|
||||||
{
|
{
|
||||||
@ -189,7 +189,7 @@ void VectorTile::points(const RectC &rect, int bits, const Range &baseMap,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<SubDiv*> subdivs = _tre->subdivs(rect, bits, baseMap);
|
QList<SubDiv*> subdivs = _tre->subdivs(rect, zoom);
|
||||||
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);
|
||||||
|
|
||||||
|
@ -23,14 +23,14 @@ public:
|
|||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
const RectC &bounds() const {return _tre->bounds();}
|
const RectC &bounds() const {return _tre->bounds();}
|
||||||
Range zooms() const {return _tre->zooms();}
|
QVector<Zoom> zooms() const {return _tre->zooms();}
|
||||||
|
|
||||||
SubFile *file(SubFile::Type type);
|
SubFile *file(SubFile::Type type);
|
||||||
|
|
||||||
void polys(const RectC &rect, int bits, const Range &baseMap,
|
void polys(const RectC &rect, const Zoom &zoom,
|
||||||
QList<MapData::Poly> *polygons, QList<MapData::Poly> *lines,
|
QList<MapData::Poly> *polygons, QList<MapData::Poly> *lines,
|
||||||
QCache<const SubDiv *, MapData::Polys> *polyCache);
|
QCache<const SubDiv *, MapData::Polys> *polyCache);
|
||||||
void points(const RectC &rect, int bits, const Range &baseMap,
|
void points(const RectC &rect, const Zoom &zoom,
|
||||||
QList<MapData::Point> *points, QCache<const SubDiv*,
|
QList<MapData::Point> *points, QCache<const SubDiv*,
|
||||||
QList<MapData::Point> > *pointCache);
|
QList<MapData::Point> > *pointCache);
|
||||||
|
|
||||||
|
49
src/map/IMG/zoom.h
Normal file
49
src/map/IMG/zoom.h
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
#ifndef IMG_ZOOM_H
|
||||||
|
#define IMG_ZOOM_H
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include "common/hash.h"
|
||||||
|
|
||||||
|
namespace IMG {
|
||||||
|
|
||||||
|
class Zoom
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Zoom() : _level(0), _bits(0) {}
|
||||||
|
Zoom(quint8 level, quint8 bits) : _level(level), _bits(bits) {}
|
||||||
|
|
||||||
|
quint8 level() const {return _level;}
|
||||||
|
quint8 bits() const {return _bits;}
|
||||||
|
|
||||||
|
bool operator<(const Zoom &other) const
|
||||||
|
{
|
||||||
|
return (_bits == other.bits())
|
||||||
|
? _level < other._level
|
||||||
|
: _bits < other._bits;
|
||||||
|
}
|
||||||
|
bool operator==(const Zoom &other) const
|
||||||
|
{
|
||||||
|
return _level == other._level && _bits == other._bits;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
quint8 _level;
|
||||||
|
quint8 _bits;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline HASH_T qHash(const Zoom &zoom)
|
||||||
|
{
|
||||||
|
return ::qHash(zoom.level()) ^ ::qHash(zoom.bits());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef QT_NO_DEBUG
|
||||||
|
inline QDebug operator<<(QDebug dbg, const IMG::Zoom &zoom)
|
||||||
|
{
|
||||||
|
dbg.nospace() << "Zoom(" << zoom.bits() << ", " << zoom.level() << ")";
|
||||||
|
return dbg.space();
|
||||||
|
}
|
||||||
|
#endif // QT_NO_DEBUG
|
||||||
|
|
||||||
|
#endif // IMG_ZOOM_H
|
Loading…
Reference in New Issue
Block a user