mirror of
https://github.com/tumic0/GPXSee.git
synced 2024-11-24 03:35: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/style.h \
|
||||
src/map/IMG/section.h \
|
||||
src/map/IMG/zoom.h \
|
||||
src/map/encmap.h \
|
||||
src/map/ENC/iso8211.h \
|
||||
src/map/gemfmap.h \
|
||||
|
@ -23,21 +23,18 @@ static SubFile::Type tileType(const QString &suffix)
|
||||
return SubFile::Unknown;
|
||||
}
|
||||
|
||||
void GMAPData::subProduct(QXmlStreamReader &reader, QString &dataDir,
|
||||
QString &baseMap)
|
||||
void GMAPData::subProduct(QXmlStreamReader &reader, QString &dataDir)
|
||||
{
|
||||
while (reader.readNextStartElement()) {
|
||||
if (reader.name() == QLatin1String("Directory"))
|
||||
dataDir = reader.readElementText();
|
||||
else if (reader.name() == QLatin1String("BaseMap"))
|
||||
baseMap = reader.readElementText();
|
||||
else
|
||||
reader.skipCurrentElement();
|
||||
}
|
||||
}
|
||||
|
||||
void GMAPData::mapProduct(QXmlStreamReader &reader, QString &dataDir,
|
||||
QString &typFile, QString &baseMap)
|
||||
QString &typFile)
|
||||
{
|
||||
while (reader.readNextStartElement()) {
|
||||
if (reader.name() == QLatin1String("Name"))
|
||||
@ -45,14 +42,13 @@ void GMAPData::mapProduct(QXmlStreamReader &reader, QString &dataDir,
|
||||
else if (reader.name() == QLatin1String("TYP"))
|
||||
typFile = reader.readElementText();
|
||||
else if (reader.name() == QLatin1String("SubProduct"))
|
||||
subProduct(reader, dataDir, baseMap);
|
||||
subProduct(reader, dataDir);
|
||||
else
|
||||
reader.skipCurrentElement();
|
||||
}
|
||||
}
|
||||
|
||||
bool GMAPData::readXML(const QString &path, QString &dataDir, QString &typFile,
|
||||
QString &baseMap)
|
||||
bool GMAPData::readXML(const QString &path, QString &dataDir, QString &typFile)
|
||||
{
|
||||
QFile file(path);
|
||||
|
||||
@ -62,7 +58,7 @@ bool GMAPData::readXML(const QString &path, QString &dataDir, QString &typFile,
|
||||
QXmlStreamReader reader(&file);
|
||||
if (reader.readNextStartElement()) {
|
||||
if (reader.name() == QLatin1String("MapProduct"))
|
||||
mapProduct(reader, dataDir, typFile, baseMap);
|
||||
mapProduct(reader, dataDir, typFile);
|
||||
else
|
||||
reader.raiseError("Not a GMAP XML file");
|
||||
}
|
||||
@ -75,7 +71,7 @@ bool GMAPData::readXML(const QString &path, QString &dataDir, QString &typFile,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GMAPData::loadTile(const QDir &dir, bool baseMap)
|
||||
bool GMAPData::loadTile(const QDir &dir)
|
||||
{
|
||||
VectorTile *tile = new VectorTile();
|
||||
|
||||
@ -103,19 +99,14 @@ bool GMAPData::loadTile(const QDir &dir, bool baseMap)
|
||||
_tileTree.Insert(min, max, tile);
|
||||
|
||||
_bounds |= tile->bounds();
|
||||
if (tile->zooms().min() < _zooms.min())
|
||||
_zooms.setMin(tile->zooms().min());
|
||||
|
||||
if (baseMap)
|
||||
_baseMap = tile->zooms();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
GMAPData::GMAPData(const QString &fileName) : MapData(fileName)
|
||||
{
|
||||
QString dataDirPath, typFilePath, baseMapPath;
|
||||
if (!readXML(fileName, dataDirPath, typFilePath, baseMapPath))
|
||||
QString dataDirPath, typFilePath;
|
||||
if (!readXML(fileName, dataDirPath, typFilePath))
|
||||
return;
|
||||
|
||||
QDir baseDir(QFileInfo(fileName).absoluteDir());
|
||||
@ -125,13 +116,11 @@ GMAPData::GMAPData(const QString &fileName) : MapData(fileName)
|
||||
}
|
||||
QDir dataDir(baseDir.filePath(dataDirPath));
|
||||
QFileInfoList ml = dataDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
|
||||
QFileInfo baseMap(dataDir.filePath(baseMapPath));
|
||||
|
||||
for (int i = 0; i < ml.size(); i++) {
|
||||
const QFileInfo &fi = ml.at(i);
|
||||
if (fi.isDir())
|
||||
loadTile(QDir(fi.absoluteFilePath()),
|
||||
fi.absoluteFilePath() == baseMap.absoluteFilePath());
|
||||
loadTile(QDir(fi.absoluteFilePath()));
|
||||
}
|
||||
|
||||
if (baseDir.exists(typFilePath)) {
|
||||
@ -143,6 +132,8 @@ GMAPData::GMAPData(const QString &fileName) : MapData(fileName)
|
||||
_errorString = "No usable map tile found";
|
||||
else
|
||||
_valid = true;
|
||||
|
||||
computeZooms();
|
||||
}
|
||||
|
||||
GMAPData::~GMAPData()
|
||||
|
@ -15,13 +15,10 @@ public:
|
||||
~GMAPData();
|
||||
|
||||
private:
|
||||
bool readXML(const QString &path, QString &dataDir, QString &typFile,
|
||||
QString &baseMap);
|
||||
void mapProduct(QXmlStreamReader &reader, QString &dataDir,
|
||||
QString &typFile, QString &baseMap);
|
||||
void subProduct(QXmlStreamReader &reader, QString &dataDir,
|
||||
QString &baseMap);
|
||||
bool loadTile(const QDir &dir, bool baseMap);
|
||||
bool readXML(const QString &path, QString &dataDir, QString &typFile);
|
||||
void mapProduct(QXmlStreamReader &reader, QString &dataDir, QString &typFile);
|
||||
void subProduct(QXmlStreamReader &reader, QString &dataDir);
|
||||
bool loadTile(const QDir &dir);
|
||||
|
||||
QList<const QString*> _files;
|
||||
};
|
||||
|
@ -156,32 +156,6 @@ bool IMGData::createTileTree(const TileMap &tileMap)
|
||||
_tileTree.Insert(min, max, tile);
|
||||
|
||||
_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);
|
||||
@ -209,6 +183,8 @@ IMGData::IMGData(const QString &fileName) : MapData(fileName)
|
||||
return;
|
||||
}
|
||||
|
||||
computeZooms();
|
||||
|
||||
_valid = true;
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@ using namespace IMG;
|
||||
bool MapData::polyCb(VectorTile *tile, void *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);
|
||||
return true;
|
||||
}
|
||||
@ -19,14 +19,13 @@ bool MapData::polyCb(VectorTile *tile, void *context)
|
||||
bool MapData::pointCb(VectorTile *tile, void *context)
|
||||
{
|
||||
PointCTX *ctx = (PointCTX*)context;
|
||||
tile->points(ctx->rect, ctx->bits, ctx->baseMap, ctx->points,
|
||||
ctx->pointCache);
|
||||
tile->points(ctx->rect, ctx->zoom, ctx->points, ctx->pointCache);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
_pointCache.setMaxCost(CACHED_SUBDIVS_COUNT);
|
||||
@ -45,7 +44,7 @@ MapData::~MapData()
|
||||
void MapData::polys(const RectC &rect, int bits, QList<Poly> *polygons,
|
||||
QList<Poly> *lines)
|
||||
{
|
||||
PolyCTX ctx(rect, bits, _baseMap, polygons, lines, &_polyCache);
|
||||
PolyCTX ctx(rect, zoom(bits), polygons, lines, &_polyCache);
|
||||
double min[2], max[2];
|
||||
|
||||
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)
|
||||
{
|
||||
PointCTX ctx(rect, bits, _baseMap, points, &_pointCache);
|
||||
PointCTX ctx(rect, zoom(bits), points, &_pointCache);
|
||||
double min[2], max[2];
|
||||
|
||||
min[0] = rect.left();
|
||||
@ -97,3 +96,41 @@ void MapData::clear()
|
||||
_polyCache.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/rtree.h"
|
||||
#include "common/range.h"
|
||||
#include "common/hash.h"
|
||||
#include "label.h"
|
||||
#include "raster.h"
|
||||
|
||||
#include "zoom.h"
|
||||
|
||||
namespace IMG {
|
||||
|
||||
@ -55,7 +56,7 @@ public:
|
||||
|
||||
const QString &name() const {return _name;}
|
||||
const RectC &bounds() const {return _bounds;}
|
||||
const Range &zooms() const {return _zooms;}
|
||||
const Range &zooms() const {return _zoomLevels;}
|
||||
const Style *style() const {return _style;}
|
||||
void polys(const RectC &rect, int bits, QList<Poly> *polygons,
|
||||
QList<Poly> *lines);
|
||||
@ -72,14 +73,16 @@ public:
|
||||
protected:
|
||||
typedef RTree<VectorTile*, double, 2> TileTree;
|
||||
|
||||
void computeZooms();
|
||||
|
||||
QString _fileName;
|
||||
QString _name;
|
||||
RectC _bounds;
|
||||
SubFile *_typ;
|
||||
Style *_style;
|
||||
TileTree _tileTree;
|
||||
Range _zooms;
|
||||
Range _baseMap;
|
||||
QList<Zoom> _zooms;
|
||||
Range _zoomLevels;
|
||||
|
||||
bool _valid;
|
||||
QString _errorString;
|
||||
@ -96,15 +99,14 @@ private:
|
||||
|
||||
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,
|
||||
QCache<const SubDiv*, MapData::Polys> *polyCache)
|
||||
: rect(rect), bits(bits), baseMap(baseMap), polygons(polygons),
|
||||
lines(lines), polyCache(polyCache) {}
|
||||
: rect(rect), zoom(zoom), polygons(polygons), lines(lines),
|
||||
polyCache(polyCache) {}
|
||||
|
||||
const RectC ▭
|
||||
int bits;
|
||||
const Range &baseMap;
|
||||
const Zoom &zoom;
|
||||
QList<MapData::Poly> *polygons;
|
||||
QList<MapData::Poly> *lines;
|
||||
QCache<const SubDiv*, MapData::Polys> *polyCache;
|
||||
@ -112,19 +114,19 @@ private:
|
||||
|
||||
struct PointCTX
|
||||
{
|
||||
PointCTX(const RectC &rect, int bits, const Range &baseMap,
|
||||
PointCTX(const RectC &rect, const Zoom &zoom,
|
||||
QList<MapData::Point> *points,
|
||||
QCache<const SubDiv*, QList<MapData::Point> > *pointCache)
|
||||
: rect(rect), bits(bits), baseMap(baseMap), points(points),
|
||||
pointCache(pointCache) {}
|
||||
: rect(rect), zoom(zoom), points(points), pointCache(pointCache) {}
|
||||
|
||||
const RectC ▭
|
||||
int bits;
|
||||
const Range &baseMap;
|
||||
const Zoom &zoom;
|
||||
QList<MapData::Point> *points;
|
||||
QCache<const SubDiv*, QList<MapData::Point> > *pointCache;
|
||||
};
|
||||
|
||||
const Zoom &zoom(int bits) const;
|
||||
|
||||
static bool polyCb(VectorTile *tile, void *context);
|
||||
static bool pointCb(VectorTile *tile, void *context);
|
||||
|
||||
@ -132,7 +134,6 @@ private:
|
||||
QCache<const SubDiv*, QList<Point> > _pointCache;
|
||||
|
||||
friend class VectorTile;
|
||||
friend struct PolyCTX;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -162,7 +162,7 @@ bool TREFile::load(int idx)
|
||||
SubDivTree *tree = new SubDivTree();
|
||||
const MapLevel &level = _levels.at(idx);
|
||||
|
||||
_subdivs.insert(level.bits, tree);
|
||||
_subdivs.insert(level.level, tree);
|
||||
|
||||
quint32 skip = 0;
|
||||
for (int i = 0; i < idx; i++)
|
||||
@ -282,27 +282,24 @@ void TREFile::clear()
|
||||
_subdivs.clear();
|
||||
}
|
||||
|
||||
int TREFile::level(int bits, const Range &baseMap)
|
||||
const TREFile::SubDivTree *TREFile::subdivs(const Zoom &zoom)
|
||||
{
|
||||
if (!baseMap.isNull()) {
|
||||
if (zooms() != baseMap && bits <= baseMap.max())
|
||||
return -1;
|
||||
if (zooms() == baseMap && bits > baseMap.max())
|
||||
return -1;
|
||||
}
|
||||
int idx = -1;
|
||||
|
||||
int idx = _firstLevel;
|
||||
|
||||
for (int i = idx + 1; i < _levels.size(); i++) {
|
||||
if (_levels.at(i).bits > bits)
|
||||
for (int i = _firstLevel; i < _levels.size(); i++) {
|
||||
if (_levels.at(i).level == zoom.level()
|
||||
&& _levels.at(i).bits == zoom.bits()) {
|
||||
idx = i;
|
||||
break;
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
if (idx < 0)
|
||||
return 0;
|
||||
|
||||
if (!_subdivs.contains(_levels.at(idx).bits) && !load(idx))
|
||||
return -1;
|
||||
if (!_subdivs.contains(_levels.at(idx).level) && !load(idx))
|
||||
return 0;
|
||||
|
||||
return _levels.at(idx).bits;
|
||||
return _subdivs.value(_levels.at(idx).level);
|
||||
}
|
||||
|
||||
static bool cb(SubDiv *subdiv, void *context)
|
||||
@ -312,11 +309,10 @@ static bool cb(SubDiv *subdiv, void *context)
|
||||
return true;
|
||||
}
|
||||
|
||||
QList<SubDiv*> TREFile::subdivs(const RectC &rect, int bits,
|
||||
const Range &baseMap)
|
||||
QList<SubDiv*> TREFile::subdivs(const RectC &rect, const Zoom &zoom)
|
||||
{
|
||||
QList<SubDiv*> list;
|
||||
SubDivTree *tree = _subdivs.value(level(bits, baseMap));
|
||||
const SubDivTree *tree = subdivs(zoom);
|
||||
double min[2], max[2];
|
||||
|
||||
min[0] = rect.left();
|
||||
@ -329,3 +325,13 @@ QList<SubDiv*> TREFile::subdivs(const RectC &rect, int bits,
|
||||
|
||||
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();
|
||||
|
||||
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
|
||||
{return (bits == _levels.last().bits) ? (_flags >> 0xb) & 7 : 0;}
|
||||
Range zooms() const
|
||||
{return Range(_levels.at(_firstLevel).bits, _levels.last().bits);}
|
||||
QVector<Zoom> zooms() const;
|
||||
|
||||
private:
|
||||
struct MapLevel {
|
||||
@ -43,7 +42,7 @@ private:
|
||||
typedef RTree<SubDiv*, double, 2> SubDivTree;
|
||||
|
||||
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,
|
||||
quint32 &points);
|
||||
|
||||
|
@ -100,7 +100,7 @@ void VectorTile::clear()
|
||||
_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,
|
||||
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++) {
|
||||
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;
|
||||
}
|
||||
|
||||
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> > *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++) {
|
||||
SubDiv *subdiv = subdivs.at(i);
|
||||
|
||||
|
@ -23,14 +23,14 @@ public:
|
||||
void clear();
|
||||
|
||||
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);
|
||||
|
||||
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,
|
||||
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> > *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