mirror of
https://github.com/tumic0/GPXSee.git
synced 2024-11-28 05:34:47 +01:00
Added support for pseudo-NT IMG maps (e.g. TopoHispania)
This commit is contained in:
parent
fcaacb4b6a
commit
37a0eec48f
@ -9,7 +9,7 @@
|
||||
|
||||
#define CHECK(condition) \
|
||||
if (!(condition)) { \
|
||||
_errorString = "Invalid/corrupted IMG file"; \
|
||||
_errorString = "Unsupported or invalid IMG file"; \
|
||||
return; \
|
||||
}
|
||||
|
||||
@ -85,11 +85,6 @@ IMG::IMG(const QString &fileName)
|
||||
&& read(type, sizeof(type)) && readValue(size) && readValue(part));
|
||||
SubFile::Type tt = SubFile::type(type);
|
||||
|
||||
if (tt == SubFile::GMP) {
|
||||
_errorString = "NT maps not supported";
|
||||
return;
|
||||
}
|
||||
|
||||
QString fn(QByteArray(name, sizeof(name)));
|
||||
if (SubFile::isTileFile(tt)) {
|
||||
VectorTile *tile;
|
||||
@ -101,7 +96,7 @@ IMG::IMG(const QString &fileName)
|
||||
tile = *it;
|
||||
|
||||
SubFile *file = part ? tile->file(tt)
|
||||
: tile->addFile(this, tt, size);
|
||||
: tile->addFile(this, tt);
|
||||
CHECK(file);
|
||||
|
||||
_file.seek(offset + 0x20);
|
||||
@ -114,7 +109,7 @@ IMG::IMG(const QString &fileName)
|
||||
} else if (tt == SubFile::TYP) {
|
||||
SubFile *typ = 0;
|
||||
if (typFile.isNull()) {
|
||||
_typ = new SubFile(this, size);
|
||||
_typ = new SubFile(this);
|
||||
typ = _typ;
|
||||
typFile = fn;
|
||||
} else if (fn == typFile)
|
||||
@ -166,7 +161,7 @@ void IMG::load()
|
||||
{
|
||||
Q_ASSERT(!_style);
|
||||
|
||||
if (_typ && _typ->isValid())
|
||||
if (_typ)
|
||||
_style = new Style(_typ);
|
||||
else {
|
||||
QFile typFile(ProgramPaths::typFile());
|
||||
|
@ -56,11 +56,11 @@ bool LBLFile::init()
|
||||
quint16 codepage;
|
||||
quint8 multiplier, poiMultiplier;
|
||||
|
||||
if (!(seek(hdl, 0x15) && readUInt32(hdl, _offset)
|
||||
if (!(seek(hdl, _gmpOffset + 0x15) && readUInt32(hdl, _offset)
|
||||
&& readUInt32(hdl, _size) && readByte(hdl, multiplier)
|
||||
&& readByte(hdl, _encoding) && seek(hdl, 0x57)
|
||||
&& readByte(hdl, _encoding) && seek(hdl, _gmpOffset + 0x57)
|
||||
&& readUInt32(hdl, _poiOffset) && readUInt32(hdl, _poiSize)
|
||||
&& readByte(hdl, poiMultiplier) && seek(hdl, 0xAA)
|
||||
&& readByte(hdl, poiMultiplier) && seek(hdl, _gmpOffset + 0xAA)
|
||||
&& readUInt16(hdl, codepage)))
|
||||
return false;
|
||||
|
||||
|
@ -9,9 +9,12 @@ class QTextCodec;
|
||||
class LBLFile : public SubFile
|
||||
{
|
||||
public:
|
||||
LBLFile(IMG *img, quint32 size)
|
||||
: SubFile(img, size), _codec(0), _offset(0), _size(0), _poiOffset(0),
|
||||
LBLFile(IMG *img)
|
||||
: SubFile(img), _codec(0), _offset(0), _size(0), _poiOffset(0),
|
||||
_poiSize(0), _poiMultiplier(0), _multiplier(0), _encoding(0) {}
|
||||
LBLFile(SubFile *gmp, quint32 offset) : SubFile(gmp, offset),
|
||||
_codec(0), _offset(0), _size(0), _poiOffset(0), _poiSize(0),
|
||||
_poiMultiplier(0), _multiplier(0), _encoding(0) {}
|
||||
|
||||
Label label(Handle &hdl, quint32 offset, bool poi = false);
|
||||
|
||||
|
@ -5,7 +5,7 @@ bool NETFile::init()
|
||||
Handle hdl;
|
||||
quint8 multiplier;
|
||||
|
||||
if (!(seek(hdl, 0x15) && readUInt32(hdl, _offset)
|
||||
if (!(seek(hdl, _gmpOffset + 0x15) && readUInt32(hdl, _offset)
|
||||
&& readUInt32(hdl, _size) && readByte(hdl, multiplier)))
|
||||
return false;
|
||||
|
||||
|
@ -6,8 +6,9 @@
|
||||
class NETFile : public SubFile
|
||||
{
|
||||
public:
|
||||
NETFile(IMG *img, quint32 size)
|
||||
: SubFile(img, size), _offset(0), _size(0), _multiplier(0) {}
|
||||
NETFile(IMG *img) : SubFile(img), _offset(0), _size(0), _multiplier(0) {}
|
||||
NETFile(SubFile *gmp, quint32 offset) : SubFile(gmp, offset),
|
||||
_offset(0), _size(0), _multiplier(0) {}
|
||||
|
||||
bool lblOffset(Handle &hdl, quint32 netOffset, quint32 &lblOffset);
|
||||
|
||||
|
@ -85,17 +85,31 @@ bool RGNFile::BitStream::finish()
|
||||
bool RGNFile::init()
|
||||
{
|
||||
Handle hdl;
|
||||
quint16 hdrLen;
|
||||
|
||||
if (!(seek(hdl, 0x15) && readUInt32(hdl, _offset)
|
||||
&& readUInt32(hdl, _size) && readUInt32(hdl, _polygonsOffset)
|
||||
&& readUInt32(hdl, _polygonsSize) && seek(hdl, 0x39)
|
||||
&& readUInt32(hdl, _linesOffset) && readUInt32(hdl, _linesSize)
|
||||
&& seek(hdl, 0x55) && readUInt32(hdl, _pointsOffset)
|
||||
&& readUInt32(hdl, _pointsSize)))
|
||||
if (!(seek(hdl, _gmpOffset) && readUInt16(hdl, hdrLen)
|
||||
&& seek(hdl, _gmpOffset + 0x15) && readUInt32(hdl, _offset)
|
||||
&& readUInt32(hdl, _size)))
|
||||
return false;
|
||||
|
||||
if (_offset + _size > size())
|
||||
return false;
|
||||
if (hdrLen >= 0x5D) {
|
||||
if (!(readUInt32(hdl, _polygonsOffset) && readUInt32(hdl, _polygonsSize)
|
||||
&& seek(hdl, _gmpOffset + 0x39) && readUInt32(hdl, _linesOffset)
|
||||
&& readUInt32(hdl, _linesSize) && seek(hdl, _gmpOffset + 0x55)
|
||||
&& readUInt32(hdl, _pointsOffset) && readUInt32(hdl, _pointsSize)))
|
||||
return false;
|
||||
}
|
||||
if (hdrLen >= 0x7D) {
|
||||
quint32 dictOffset, dictSize;
|
||||
if (!(seek(hdl, _gmpOffset + 0x71) && readUInt32(hdl, dictOffset)
|
||||
&& readUInt32(hdl, dictSize)))
|
||||
return false;
|
||||
|
||||
if (dictSize || dictOffset) {
|
||||
qWarning("%s: NT compression not supported", qPrintable(fileName()));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -404,9 +418,6 @@ void RGNFile::objects(const RectC &rect, const SubDiv *subdiv, LBLFile *lbl,
|
||||
{
|
||||
Handle rgnHdl, lblHdl, netHdl;
|
||||
|
||||
if (!_size && !init())
|
||||
return;
|
||||
|
||||
QVector<RGNFile::Segment> seg(segments(rgnHdl, subdiv));
|
||||
for (int i = 0; i < seg.size(); i++) {
|
||||
switch (seg.at(i).type()) {
|
||||
@ -436,9 +447,6 @@ void RGNFile::extObjects(const RectC &rect, const SubDiv *subdiv, LBLFile *lbl,
|
||||
{
|
||||
Handle rgnHdl, lblHdl;
|
||||
|
||||
if (!_size && !init())
|
||||
return;
|
||||
|
||||
if (polygons && subdiv->polygonsOffset() != subdiv->polygonsEnd()) {
|
||||
quint32 start = _polygonsOffset + subdiv->polygonsOffset();
|
||||
quint32 end = subdiv->polygonsEnd()
|
||||
|
@ -11,10 +11,15 @@ class NETFile;
|
||||
class RGNFile : public SubFile
|
||||
{
|
||||
public:
|
||||
RGNFile(IMG *img, quint32 size)
|
||||
: SubFile(img, size), _offset(0), _size(0), _polygonsOffset(0),
|
||||
_polygonsSize(), _linesOffset(), _linesSize(), _pointsOffset(),
|
||||
_pointsSize() {}
|
||||
RGNFile(IMG *img)
|
||||
: SubFile(img), _offset(0), _size(0), _polygonsOffset(0),
|
||||
_polygonsSize(0), _linesOffset(0), _linesSize(0), _pointsOffset(0),
|
||||
_pointsSize(0) {}
|
||||
RGNFile(SubFile *gmp, quint32 offset) : SubFile(gmp, offset), _offset(0),
|
||||
_size(0), _polygonsOffset(0), _polygonsSize(0), _linesOffset(0),
|
||||
_linesSize(0), _pointsOffset(0), _pointsSize(0) {}
|
||||
|
||||
bool init();
|
||||
|
||||
void objects(const RectC &rect, const SubDiv *subdiv, LBLFile *lbl,
|
||||
NETFile *net, QList<IMG::Poly> *polygons, QList<IMG::Poly> *lines,
|
||||
@ -73,7 +78,6 @@ private:
|
||||
static bool sign(BitStream &bs, int &val);
|
||||
static int bitSize(quint8 baseSize, bool variableSign, bool extraBit);
|
||||
|
||||
bool init();
|
||||
QVector<Segment> segments(Handle &hdl, const SubDiv *subdiv) const;
|
||||
bool polyObjects(const RectC &rect, Handle &hdl, const SubDiv *subdiv,
|
||||
const Segment &segment, LBLFile *lbl, Handle &lblHdl, NETFile *net,
|
||||
|
@ -942,7 +942,7 @@ Style::Style(SubFile *typ)
|
||||
defaultPolygonStyle();
|
||||
defaultPointStyle();
|
||||
|
||||
if (typ && typ->isValid())
|
||||
if (typ)
|
||||
parseTYPFile(typ);
|
||||
}
|
||||
|
||||
|
@ -20,21 +20,13 @@ SubFile::Type SubFile::type(const char str[3])
|
||||
return Unknown;
|
||||
}
|
||||
|
||||
SubFile::SubFile(QFile *file) : _img(0), _file(file), _size(0)
|
||||
SubFile::SubFile(QFile *file) :_gmpOffset(0), _img(0), _file(file), _blocks(0)
|
||||
{
|
||||
if (!_file->open(QIODevice::ReadOnly))
|
||||
qWarning("Error opening %s: %s", qPrintable(_file->fileName()),
|
||||
qPrintable(_file->errorString()));
|
||||
}
|
||||
|
||||
bool SubFile::isValid() const
|
||||
{
|
||||
return _file
|
||||
? _file->isOpen()
|
||||
: ((quint32)_img->blockSize() * (quint32)_blocks.size() - _size
|
||||
< (quint32)_img->blockSize());
|
||||
}
|
||||
|
||||
bool SubFile::seek(Handle &handle, quint32 pos) const
|
||||
{
|
||||
Q_ASSERT(_img || _file);
|
||||
@ -46,9 +38,9 @@ bool SubFile::seek(Handle &handle, quint32 pos) const
|
||||
int blockNum = pos / blockSize;
|
||||
|
||||
if (handle.blockNum != blockNum) {
|
||||
if (blockNum >= _blocks.size())
|
||||
if (blockNum >= _blocks->size())
|
||||
return false;
|
||||
if (!_img->readBlock(_blocks.at(blockNum), handle.data))
|
||||
if (!_img->readBlock(_blocks->at(blockNum), handle.data))
|
||||
return false;
|
||||
handle.blockNum = blockNum;
|
||||
}
|
||||
@ -74,11 +66,6 @@ bool SubFile::readByte(Handle &handle, quint8 &val) const
|
||||
}
|
||||
}
|
||||
|
||||
quint32 SubFile::size() const
|
||||
{
|
||||
return _file ? (quint32)_file->size() : _size;
|
||||
}
|
||||
|
||||
QString SubFile::fileName() const
|
||||
{
|
||||
return _file ? _file->fileName() : _img->fileName();
|
||||
@ -88,15 +75,15 @@ QString SubFile::fileName() const
|
||||
QDebug operator<<(QDebug dbg, const SubFile &file)
|
||||
{
|
||||
bool continuous = true;
|
||||
for (int i = 1; i < file._blocks.size(); i++) {
|
||||
if (file._blocks.at(i) != file._blocks.at(i-1) + 1) {
|
||||
for (int i = 1; i < file._blocks->size(); i++) {
|
||||
if (file._blocks->at(i) != file._blocks->at(i-1) + 1) {
|
||||
continuous = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
dbg.nospace() << "SubFile(" << file._size << ", " << file._blocks.size()
|
||||
<< ", " << continuous << ")";
|
||||
dbg.nospace() << "SubFile(" << file._blocks->size() << ", "
|
||||
<< continuous << ")";
|
||||
return dbg.space();
|
||||
}
|
||||
#endif // QT_NO_DEBUG
|
||||
|
@ -22,13 +22,14 @@ public:
|
||||
int pos;
|
||||
};
|
||||
|
||||
SubFile(IMG *img, quint32 size) : _img(img), _file(0), _size(size) {}
|
||||
SubFile(IMG *img) : _gmpOffset(0), _img(img), _file(0),
|
||||
_blocks(&_blockData) {}
|
||||
SubFile(SubFile *gmp, quint32 offset) : _gmpOffset(offset), _img(gmp->_img),
|
||||
_file(0), _blocks(&(gmp->_blockData)) {}
|
||||
SubFile(QFile *file);
|
||||
|
||||
void addBlock(quint16 block) {_blocks.append(block);}
|
||||
bool isValid() const;
|
||||
void addBlock(quint16 block) {_blocks->append(block);}
|
||||
|
||||
quint32 size() const;
|
||||
bool seek(Handle &handle, quint32 pos) const;
|
||||
bool readByte(Handle &handle, quint8 &val) const;
|
||||
|
||||
@ -80,20 +81,26 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
quint16 offset() const {return _blocks.first();}
|
||||
quint16 offset() const {return _blocks->first();}
|
||||
QString fileName() const;
|
||||
|
||||
static Type type(const char str[3]);
|
||||
static bool isTileFile(Type type)
|
||||
{return (type == TRE || type == LBL || type == RGN || type == NET);}
|
||||
{
|
||||
return (type == TRE || type == LBL || type == RGN || type == NET
|
||||
|| type == GMP);
|
||||
}
|
||||
|
||||
friend QDebug operator<<(QDebug dbg, const SubFile &file);
|
||||
|
||||
protected:
|
||||
quint32 _gmpOffset;
|
||||
|
||||
private:
|
||||
IMG *_img;
|
||||
QFile *_file;
|
||||
quint32 _size;
|
||||
QVector<quint16> _blocks;
|
||||
QVector<quint16> *_blocks;
|
||||
QVector<quint16> _blockData;
|
||||
};
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
|
@ -43,28 +43,28 @@ bool TREFile::init()
|
||||
quint8 locked;
|
||||
quint16 hdrLen;
|
||||
|
||||
if (!(seek(hdl, 0) && readUInt16(hdl, hdrLen)
|
||||
&& seek(hdl, 0x0D) && readByte(hdl, locked)))
|
||||
if (!(seek(hdl, _gmpOffset) && readUInt16(hdl, hdrLen)
|
||||
&& seek(hdl, _gmpOffset + 0x0D) && readByte(hdl, locked)))
|
||||
return false;
|
||||
|
||||
// Tile bounds
|
||||
qint32 north, east, south, west;
|
||||
if (!(seek(hdl, 0x15) && readInt24(hdl, north) && readInt24(hdl, east)
|
||||
&& readInt24(hdl, south) && readInt24(hdl, west)))
|
||||
if (!(seek(hdl, _gmpOffset + 0x15) && readInt24(hdl, north)
|
||||
&& readInt24(hdl, east) && readInt24(hdl, south) && readInt24(hdl, west)))
|
||||
return false;
|
||||
_bounds = RectC(Coordinates(toWGS84(west), toWGS84(north)),
|
||||
Coordinates(toWGS84(east), toWGS84(south)));
|
||||
|
||||
// Levels & subdivs info
|
||||
quint32 levelsOffset, levelsSize, subdivSize;
|
||||
if (!(seek(hdl, 0x21) && readUInt32(hdl, levelsOffset)
|
||||
if (!(seek(hdl, _gmpOffset + 0x21) && readUInt32(hdl, levelsOffset)
|
||||
&& readUInt32(hdl, levelsSize) && readUInt32(hdl, _subdivOffset)
|
||||
&& readUInt32(hdl, subdivSize)))
|
||||
return false;
|
||||
|
||||
// TRE7 info
|
||||
if (hdrLen > 0x9A) {
|
||||
if (!(seek(hdl, 0x7C) && readUInt32(hdl, _extended.offset)
|
||||
if (!(seek(hdl, _gmpOffset + 0x7C) && readUInt32(hdl, _extended.offset)
|
||||
&& readUInt32(hdl, _extended.size)
|
||||
&& readUInt16(hdl, _extended.itemSize)))
|
||||
return false;
|
||||
@ -80,7 +80,7 @@ bool TREFile::init()
|
||||
if (locked) {
|
||||
quint32 key;
|
||||
quint8 unlocked[64];
|
||||
if (!seek(hdl, 0xAA) || !readUInt32(hdl, key))
|
||||
if (!seek(hdl, _gmpOffset + 0xAA) || !readUInt32(hdl, key))
|
||||
return false;
|
||||
unlock(unlocked, levels, levelsSize, key);
|
||||
memcpy(levels, unlocked, levelsSize);
|
||||
|
@ -13,7 +13,8 @@ class SubDiv;
|
||||
class TREFile : public SubFile
|
||||
{
|
||||
public:
|
||||
TREFile(IMG *img, quint32 size) : SubFile(img, size) {}
|
||||
TREFile(IMG *img) : SubFile(img) {}
|
||||
TREFile(SubFile *gmp, quint32 offset) : SubFile(gmp, offset) {}
|
||||
~TREFile();
|
||||
|
||||
bool init();
|
||||
|
@ -11,26 +11,31 @@ SubFile *VectorTile::file(SubFile::Type type)
|
||||
return _lbl;
|
||||
case SubFile::NET:
|
||||
return _net;
|
||||
case SubFile::GMP:
|
||||
return _gmp;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
SubFile *VectorTile::addFile(IMG *img, SubFile::Type type, quint32 size)
|
||||
SubFile *VectorTile::addFile(IMG *img, SubFile::Type type)
|
||||
{
|
||||
switch (type) {
|
||||
case SubFile::TRE:
|
||||
_tre = new TREFile(img, size);
|
||||
_tre = new TREFile(img);
|
||||
return _tre;
|
||||
case SubFile::RGN:
|
||||
_rgn = new RGNFile(img, size);
|
||||
_rgn = new RGNFile(img);
|
||||
return _rgn;
|
||||
case SubFile::LBL:
|
||||
_lbl = new LBLFile(img, size);
|
||||
_lbl = new LBLFile(img);
|
||||
return _lbl;
|
||||
case SubFile::NET:
|
||||
_net = new NETFile(img, size);
|
||||
_net = new NETFile(img);
|
||||
return _net;
|
||||
case SubFile::GMP:
|
||||
_gmp = new SubFile(img);
|
||||
return _gmp;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@ -38,14 +43,30 @@ SubFile *VectorTile::addFile(IMG *img, SubFile::Type type, quint32 size)
|
||||
|
||||
bool VectorTile::init()
|
||||
{
|
||||
if (!(_tre && _tre->isValid() && _tre->init() && _rgn
|
||||
&& _rgn->isValid()))
|
||||
if (_gmp && !initGMP())
|
||||
return false;
|
||||
if (_lbl && !_lbl->isValid())
|
||||
|
||||
if (!(_tre && _tre->init() && _rgn && _rgn->init()))
|
||||
return false;
|
||||
if (_net && !_net->isValid())
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VectorTile::initGMP()
|
||||
{
|
||||
SubFile::Handle hdl;
|
||||
quint32 tre, rgn, lbl, net;
|
||||
|
||||
if (!(_gmp->seek(hdl, 0x19) && _gmp->readUInt32(hdl, tre)
|
||||
&& _gmp->readUInt32(hdl, rgn) && _gmp->readUInt32(hdl, lbl)
|
||||
&& _gmp->readUInt32(hdl, net)))
|
||||
return false;
|
||||
|
||||
_tre = new TREFile(_gmp, tre);
|
||||
_rgn = new RGNFile(_gmp, rgn);
|
||||
_lbl = new LBLFile(_gmp, lbl);
|
||||
_net = new NETFile(_gmp, net);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -10,8 +10,9 @@
|
||||
|
||||
class VectorTile {
|
||||
public:
|
||||
VectorTile() : _tre(0), _rgn(0), _lbl(0), _net(0) {}
|
||||
~VectorTile() {delete _tre; delete _rgn; delete _lbl; delete _net;}
|
||||
VectorTile() : _tre(0), _rgn(0), _lbl(0), _net(0), _gmp(0) {}
|
||||
~VectorTile()
|
||||
{delete _tre; delete _rgn; delete _lbl; delete _net; delete _gmp;}
|
||||
|
||||
bool init();
|
||||
void clear() {_tre->clear();}
|
||||
@ -19,7 +20,7 @@ public:
|
||||
const RectC &bounds() const {return _tre->bounds();}
|
||||
|
||||
SubFile *file(SubFile::Type type);
|
||||
SubFile *addFile(IMG *img, SubFile::Type type, quint32 size);
|
||||
SubFile *addFile(IMG *img, SubFile::Type type);
|
||||
|
||||
void objects(const RectC &rect, int bits, QList<IMG::Poly> *polygons,
|
||||
QList<IMG::Poly> *lines, QList<IMG::Point> *points) const;
|
||||
@ -27,10 +28,13 @@ public:
|
||||
friend QDebug operator<<(QDebug dbg, const VectorTile &tile);
|
||||
|
||||
private:
|
||||
bool initGMP();
|
||||
|
||||
TREFile *_tre;
|
||||
RGNFile *_rgn;
|
||||
LBLFile *_lbl;
|
||||
NETFile *_net;
|
||||
SubFile *_gmp;
|
||||
};
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
|
Loading…
Reference in New Issue
Block a user