mirror of
https://github.com/tumic0/GPXSee.git
synced 2024-11-27 21:24:47 +01:00
Huffman encoded labels
+ more or less related fixes/refactoring
This commit is contained in:
parent
0644bb72a0
commit
f139d33502
@ -93,8 +93,10 @@ HEADERS += src/common/config.h \
|
||||
src/map/IMG/bitstream.h \
|
||||
src/map/IMG/deltastream.h \
|
||||
src/map/IMG/gmap.h \
|
||||
src/map/IMG/huffmanbuffer.h \
|
||||
src/map/IMG/huffmanstream.h \
|
||||
src/map/IMG/huffmantable.h \
|
||||
src/map/IMG/huffmantext.h \
|
||||
src/map/IMG/nodfile.h \
|
||||
src/map/IMG/mapdata.h \
|
||||
src/map/IMG/rastertile.h \
|
||||
@ -258,8 +260,10 @@ SOURCES += src/main.cpp \
|
||||
src/map/IMG/bitstream.cpp \
|
||||
src/map/IMG/deltastream.cpp \
|
||||
src/map/IMG/gmap.cpp \
|
||||
src/map/IMG/huffmanbuffer.cpp \
|
||||
src/map/IMG/huffmanstream.cpp \
|
||||
src/map/IMG/huffmantable.cpp \
|
||||
src/map/IMG/huffmantext.cpp \
|
||||
src/map/IMG/nodfile.cpp \
|
||||
src/map/IMG/mapdata.cpp \
|
||||
src/map/IMG/rastertile.cpp \
|
||||
|
@ -15,4 +15,15 @@ inline double toWGS24(qint32 v)
|
||||
return toWGS32(LS(v, 8));
|
||||
}
|
||||
|
||||
inline quint8 vs(const quint8 b0)
|
||||
{
|
||||
static const quint8 sizes[] = {4, 1, 2, 1, 3, 1, 2, 1};
|
||||
return sizes[b0 & 0x07];
|
||||
}
|
||||
|
||||
inline quint8 bs(const quint8 val)
|
||||
{
|
||||
return (val + 7) >> 3;
|
||||
}
|
||||
|
||||
#endif // GARMIN_H
|
||||
|
@ -81,7 +81,11 @@ bool GMAP::loadTile(const QDir &dir, bool baseMap)
|
||||
QFileInfoList ml = dir.entryInfoList(QDir::Files);
|
||||
for (int i = 0; i < ml.size(); i++) {
|
||||
const QFileInfo &fi = ml.at(i);
|
||||
tile->addFile(fi.absoluteFilePath(), tileType(fi.suffix()));
|
||||
SubFile::Type tt = tileType(fi.suffix());
|
||||
if (VectorTile::isTileFile(tt)) {
|
||||
_files.append(new QString(fi.absoluteFilePath()));
|
||||
tile->addFile(_files.last(), tt);
|
||||
}
|
||||
}
|
||||
|
||||
if (!tile->init()) {
|
||||
@ -131,8 +135,10 @@ GMAP::GMAP(const QString &fileName) : _fileName(fileName)
|
||||
fi.absoluteFilePath() == baseMap.absoluteFilePath());
|
||||
}
|
||||
|
||||
if (baseDir.exists(typFilePath))
|
||||
_typ = new SubFile(baseDir.filePath(typFilePath));
|
||||
if (baseDir.exists(typFilePath)) {
|
||||
_files.append(new QString(baseDir.filePath(typFilePath)));
|
||||
_typ = new SubFile(_files.last());
|
||||
}
|
||||
|
||||
if (!_tileTree.Count())
|
||||
_errorString = "No usable map tile found";
|
||||
@ -140,6 +146,11 @@ GMAP::GMAP(const QString &fileName) : _fileName(fileName)
|
||||
_valid = true;
|
||||
}
|
||||
|
||||
GMAP::~GMAP()
|
||||
{
|
||||
qDeleteAll(_files);
|
||||
}
|
||||
|
||||
bool GMAP::isGMAP(const QString &path)
|
||||
{
|
||||
QFile file(path);
|
||||
|
@ -10,6 +10,7 @@ class GMAP : public MapData
|
||||
{
|
||||
public:
|
||||
GMAP(const QString &fileName);
|
||||
~GMAP();
|
||||
|
||||
QString fileName() const {return _fileName;}
|
||||
|
||||
@ -25,6 +26,7 @@ private:
|
||||
bool loadTile(const QDir &dir, bool baseMap);
|
||||
|
||||
QString _fileName;
|
||||
QList<const QString*> _files;
|
||||
};
|
||||
|
||||
#endif // GMAP_H
|
||||
|
24
src/map/IMG/huffmanbuffer.cpp
Normal file
24
src/map/IMG/huffmanbuffer.cpp
Normal file
@ -0,0 +1,24 @@
|
||||
#include "rgnfile.h"
|
||||
#include "huffmanbuffer.h"
|
||||
|
||||
bool HuffmanBuffer::load(const RGNFile *rgn, SubFile::Handle &rgnHdl)
|
||||
{
|
||||
quint32 recordSize, recordOffset = rgn->dictOffset();
|
||||
|
||||
for (int i = 0; i <= _id; i++) {
|
||||
if (!rgn->seek(rgnHdl, recordOffset))
|
||||
return false;
|
||||
if (!rgn->readVUInt32(rgnHdl, recordSize))
|
||||
return false;
|
||||
recordOffset = rgn->pos(rgnHdl) + recordSize;
|
||||
if (recordOffset > rgn->dictOffset() + rgn->dictSize())
|
||||
return false;
|
||||
};
|
||||
|
||||
resize(recordSize);
|
||||
for (int i = 0; i < QByteArray::size(); i++)
|
||||
if (!rgn->readUInt8(rgnHdl, *((quint8*)(data() + i))))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
21
src/map/IMG/huffmanbuffer.h
Normal file
21
src/map/IMG/huffmanbuffer.h
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef HUFFMANBUFFER_H
|
||||
#define HUFFMANBUFFER_H
|
||||
|
||||
#include <QByteArray>
|
||||
#include "subfile.h"
|
||||
|
||||
class RGNFile;
|
||||
|
||||
class HuffmanBuffer : public QByteArray
|
||||
{
|
||||
public:
|
||||
HuffmanBuffer(quint8 id) : _id(id) {}
|
||||
|
||||
quint8 id() const {return _id;}
|
||||
bool load(const RGNFile *rgn, SubFile::Handle &rgnHdl);
|
||||
|
||||
private:
|
||||
quint8 _id;
|
||||
};
|
||||
|
||||
#endif // HUFFMANBUFFER_H
|
@ -1,17 +1,7 @@
|
||||
#include "common/garmin.h"
|
||||
#include "huffmantable.h"
|
||||
|
||||
|
||||
static quint8 vs(const quint8 b0)
|
||||
{
|
||||
static const quint8 sizes[] = {4, 1, 2, 1, 3, 1, 2, 1};
|
||||
return sizes[b0 & 0x07];
|
||||
}
|
||||
|
||||
static inline quint8 bs(const quint8 val)
|
||||
{
|
||||
return (val + 7) >> 3;
|
||||
}
|
||||
|
||||
static inline quint32 readVUint32(const quint8 *buffer, quint32 bytes)
|
||||
{
|
||||
quint32 val = 0;
|
||||
@ -22,10 +12,9 @@ static inline quint32 readVUint32(const quint8 *buffer, quint32 bytes)
|
||||
return val;
|
||||
}
|
||||
|
||||
bool HuffmanTable::load(const SubFile &file, SubFile::Handle &hdl,
|
||||
quint32 offset, quint32 size, quint32 id)
|
||||
bool HuffmanTable::load(const RGNFile *rgn, SubFile::Handle &rgnHdl)
|
||||
{
|
||||
if (!getBuffer(file, hdl, offset, size, id))
|
||||
if (!_buffer.load(rgn, rgnHdl))
|
||||
return false;
|
||||
|
||||
_s0 = (quint8)_buffer.at(0) & 0x0F;
|
||||
@ -42,31 +31,6 @@ bool HuffmanTable::load(const SubFile &file, SubFile::Handle &hdl,
|
||||
_s10 = _s14 + _s1c * _s1d;
|
||||
_s18 = _s10 + (_s1 << _s0);
|
||||
|
||||
_id = id;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HuffmanTable::getBuffer(const SubFile &file, SubFile::Handle &hdl,
|
||||
quint32 offset, quint32 size, quint8 id)
|
||||
{
|
||||
quint32 recordSize, recordOffset = offset;
|
||||
|
||||
for (int i = 0; i <= id; i++) {
|
||||
if (!file.seek(hdl, recordOffset))
|
||||
return false;
|
||||
if (!file.readVUInt32(hdl, recordSize))
|
||||
return false;
|
||||
recordOffset = file.pos(hdl) + recordSize;
|
||||
if (recordOffset > offset + size)
|
||||
return false;
|
||||
};
|
||||
|
||||
_buffer.resize(recordSize);
|
||||
for (int i = 0; i < _buffer.size(); i++)
|
||||
if (!file.readUInt8(hdl, *((quint8*)(_buffer.data() + i))))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1,31 +1,26 @@
|
||||
#ifndef HUFFMANTABLE_H
|
||||
#define HUFFMANTABLE_H
|
||||
|
||||
#include "subfile.h"
|
||||
#include "huffmanbuffer.h"
|
||||
|
||||
class RGNFile;
|
||||
|
||||
class HuffmanTable {
|
||||
public:
|
||||
HuffmanTable() : _s2(0) {}
|
||||
HuffmanTable(quint8 id) : _buffer(id) {}
|
||||
|
||||
bool load(const SubFile &file, SubFile::Handle &hdl, quint32 offset,
|
||||
quint32 size, quint32 id);
|
||||
bool isNull() const {return _s2 == 0;}
|
||||
bool load(const RGNFile *rgn, SubFile::Handle &rgnHdl);
|
||||
quint8 maxSymbolSize() const {return _s2;}
|
||||
quint32 symbol(quint32 data, quint8 &size) const;
|
||||
|
||||
quint8 id() const {return _id;}
|
||||
quint8 id() const {return _buffer.id();}
|
||||
|
||||
private:
|
||||
bool getBuffer(const SubFile &file, SubFile::Handle &hdl, quint32 offset,
|
||||
quint32 size, quint8 id);
|
||||
|
||||
QByteArray _buffer;
|
||||
HuffmanBuffer _buffer;
|
||||
quint8 _s0, _s1, _s2, _s3;
|
||||
quint8 *_s10, *_s14, *_s18;
|
||||
quint8 _s1c, _s1d, _s1e, _s1f, _s20;
|
||||
quint16 _s22;
|
||||
|
||||
quint8 _id;
|
||||
};
|
||||
|
||||
#endif // HUFFMANTABLE_H
|
||||
|
169
src/map/IMG/huffmantext.cpp
Normal file
169
src/map/IMG/huffmantext.cpp
Normal file
@ -0,0 +1,169 @@
|
||||
#include "common/garmin.h"
|
||||
#include "subfile.h"
|
||||
#include "huffmantext.h"
|
||||
|
||||
|
||||
static inline quint32 readVUint32(const quint8 *buffer, quint32 bytes)
|
||||
{
|
||||
quint32 val = 0;
|
||||
|
||||
for (quint32 i = 0; i < bytes; i++)
|
||||
val = val | (quint32)*(buffer - i) << ((bytes - i - 1) << 3);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
bool HuffmanText::load(const RGNFile *rgn, SubFile::Handle &rgnHdl)
|
||||
{
|
||||
if (!_buffer.load(rgn, rgnHdl))
|
||||
return false;
|
||||
|
||||
quint8 *buffer = (quint8 *)_buffer.constData();
|
||||
_b0 = buffer[0];
|
||||
_b1 = buffer[1];
|
||||
_b2 = buffer[2];
|
||||
_b3 = buffer[3];
|
||||
_vs = vs(buffer[4]);
|
||||
_bs3 = bs(_b3);
|
||||
_bs1 = bs(_b1);
|
||||
_mul = _bs1 + 1 + _vs;
|
||||
_bp1 = buffer + _vs + 4;
|
||||
_bp2 = _bp1 + _mul * _b2;
|
||||
_bp3 = _bp2 + ((_bs3 + 1) << (_b0 & 0xf));
|
||||
_bp4 = _bp3 - 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HuffmanText::fetch(const SubFile *file, SubFile::Handle &hdl,
|
||||
quint32 &data, quint32 &bits, quint32 &usedBits, quint32 &usedData) const
|
||||
{
|
||||
quint32 rs, ls, old;
|
||||
|
||||
bits = _b1 - bits;
|
||||
|
||||
if (usedBits < bits) {
|
||||
old = usedBits ? usedData >> (0x20 - usedBits) : 0;
|
||||
if (!file->readVUInt32SW(hdl, 4, usedData))
|
||||
return false;
|
||||
ls = bits - usedBits;
|
||||
rs = 0x20 - (bits - usedBits);
|
||||
old = usedData >> rs | old << ls;
|
||||
} else {
|
||||
ls = bits;
|
||||
rs = usedBits - bits;
|
||||
old = usedData >> (0x20 - bits);
|
||||
}
|
||||
|
||||
usedData = usedData << ls;
|
||||
data = data | old << (0x20 - _b1);
|
||||
usedBits = rs;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HuffmanText::decode(const SubFile *file, SubFile::Handle &hdl,
|
||||
QVector<quint8> &str) const
|
||||
{
|
||||
quint32 bits = 0;
|
||||
quint32 data = 0;
|
||||
quint32 usedBits = 0;
|
||||
quint32 usedData = 0;
|
||||
quint32 ls = 8;
|
||||
quint32 lo = _vs * 8 - 8;
|
||||
|
||||
|
||||
while (true) {
|
||||
if (!fetch(file, hdl, data, bits, usedBits, usedData))
|
||||
return false;
|
||||
|
||||
quint32 off = (data >> (0x20 - (_b0 & 0xf))) * (_bs3 + 1);
|
||||
quint32 sb = _bp2[off];
|
||||
quint32 ss = 0;
|
||||
quint32 sym = _b2 - 1;
|
||||
quint32 size;
|
||||
|
||||
if ((_b0 & 0xf) == 0 || (sb & 1) == 0) {
|
||||
if ((_b0 & 0xf) != 0) {
|
||||
ss = sb >> 1;
|
||||
sym = _bp2[off + 1];
|
||||
}
|
||||
|
||||
quint8 *tp = _bp1 + ss * _mul;
|
||||
quint32 sd = data >> (0x20 - _b1);
|
||||
while (ss < sym) {
|
||||
quint32 cnt = (sym + 1 + ss) >> 1;
|
||||
quint8 *prev = _bp1 + cnt * _mul;
|
||||
quint32 nd = readVUint32(prev + _bs1 - 1, _bs1);
|
||||
|
||||
if (sd <= nd) {
|
||||
sym = cnt - (sd < nd);
|
||||
if (sd < nd) {
|
||||
prev = tp;
|
||||
cnt = ss;
|
||||
}
|
||||
}
|
||||
tp = prev;
|
||||
ss = cnt;
|
||||
}
|
||||
|
||||
quint32 o1 = readVUint32(tp + _bs1 - 1, _bs1);
|
||||
tp = tp + _bs1;
|
||||
quint32 o2 = readVUint32(tp + _vs, _vs);
|
||||
size = tp[0];
|
||||
quint32 os = (sd - o1) >> (_b1 - size);
|
||||
|
||||
if ((_b0 & 0x10) == 0) {
|
||||
sym = readVUint32(_bp4 + (o2 + 1 + os) * _bs3, _bs3);
|
||||
} else {
|
||||
quint32 v = (os + o2) * _b3;
|
||||
quint32 idx = v >> 3;
|
||||
quint32 r = v & 7;
|
||||
quint32 shift = 8 - r;
|
||||
sym = _bp3[idx] >> r;
|
||||
if (shift < _b3) {
|
||||
quint32 sz = bs(_b3 - shift);
|
||||
quint32 val = readVUint32(_bp3 + idx + sz, sz);
|
||||
sym = sym | val << shift;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
sym = readVUint32(_bp2 + off + _bs3, _bs3);
|
||||
size = (sb >> 1);
|
||||
}
|
||||
|
||||
if (_b1 < size)
|
||||
return false;
|
||||
data = data << size;
|
||||
bits = _b1 - size;
|
||||
|
||||
if ((_b3 & 7) == 0) {
|
||||
for (quint32 i = 0; i < (_b3 >> 3); i++) {
|
||||
str.append((quint8)sym);
|
||||
if (((quint8)sym == '\0'))
|
||||
return true;
|
||||
sym = sym >> 8;
|
||||
}
|
||||
} else {
|
||||
quint32 cnt = _b3;
|
||||
|
||||
if (ls <= _b3) {
|
||||
do {
|
||||
quint32 shift = ls;
|
||||
lo = sym << (8 - shift) | (quint32)((quint8)lo >> shift);
|
||||
sym = sym >> shift;
|
||||
str.append((uchar)lo);
|
||||
if (((uchar)lo == '\0'))
|
||||
return true;
|
||||
cnt = cnt - ls;
|
||||
ls = 8;
|
||||
} while (7 < cnt);
|
||||
ls = 8;
|
||||
}
|
||||
if (cnt != 0) {
|
||||
lo = sym << (8 - cnt) | (quint32)((quint8)lo >> cnt);
|
||||
ls = ls - cnt;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
35
src/map/IMG/huffmantext.h
Normal file
35
src/map/IMG/huffmantext.h
Normal file
@ -0,0 +1,35 @@
|
||||
#ifndef HUFFMANTEXT_H
|
||||
#define HUFFMANTEXT_H
|
||||
|
||||
#include "huffmanbuffer.h"
|
||||
|
||||
class HuffmanText
|
||||
{
|
||||
public:
|
||||
HuffmanText() : _buffer(0) {}
|
||||
|
||||
bool load(const RGNFile *rgn, SubFile::Handle &rgnHdl);
|
||||
bool decode(const SubFile *file, SubFile::Handle &hdl,
|
||||
QVector<quint8> &str) const;
|
||||
|
||||
private:
|
||||
bool fetch(const SubFile *file, SubFile::Handle &hdl, quint32 &data,
|
||||
quint32 &bits, quint32 &usedBits, quint32 &usedData) const;
|
||||
|
||||
HuffmanBuffer _buffer;
|
||||
|
||||
quint32 _b0;
|
||||
quint32 _b1;
|
||||
quint32 _b2;
|
||||
quint32 _b3;
|
||||
quint32 _vs;
|
||||
quint32 _bs3;
|
||||
quint32 _bs1;
|
||||
quint32 _mul;
|
||||
quint8 *_bp1;
|
||||
quint8 *_bp2;
|
||||
quint8 *_bp3;
|
||||
quint8 *_bp4;
|
||||
};
|
||||
|
||||
#endif // HUFFMANTEXT_H
|
@ -1,4 +1,6 @@
|
||||
#include <QTextCodec>
|
||||
#include "huffmantext.h"
|
||||
#include "rgnfile.h"
|
||||
#include "lblfile.h"
|
||||
|
||||
enum Charset {Normal, Symbol, Special};
|
||||
@ -55,21 +57,48 @@ static QString capitalized(const QString &str)
|
||||
}
|
||||
|
||||
|
||||
bool LBLFile::init(Handle &hdl)
|
||||
LBLFile::~LBLFile()
|
||||
{
|
||||
quint16 codepage;
|
||||
quint8 multiplier, poiMultiplier;
|
||||
delete _huffmanText;
|
||||
delete _table;
|
||||
}
|
||||
|
||||
if (!(seek(hdl, _gmpOffset + 0x15) && readUInt32(hdl, _offset)
|
||||
&& readUInt32(hdl, _size) && readUInt8(hdl, multiplier)
|
||||
bool LBLFile::load(Handle &hdl, const RGNFile *rgn, Handle &rgnHdl)
|
||||
{
|
||||
quint16 hdrLen, codepage;
|
||||
|
||||
if (!(seek(hdl, _gmpOffset) && readUInt16(hdl, hdrLen)
|
||||
&& seek(hdl, _gmpOffset + 0x15) && readUInt32(hdl, _offset)
|
||||
&& readUInt32(hdl, _size) && readUInt8(hdl, _multiplier)
|
||||
&& readUInt8(hdl, _encoding) && seek(hdl, _gmpOffset + 0x57)
|
||||
&& readUInt32(hdl, _poiOffset) && readUInt32(hdl, _poiSize)
|
||||
&& readUInt8(hdl, poiMultiplier) && seek(hdl, _gmpOffset + 0xAA)
|
||||
&& readUInt8(hdl, _poiMultiplier) && seek(hdl, _gmpOffset + 0xAA)
|
||||
&& readUInt16(hdl, codepage)))
|
||||
return false;
|
||||
|
||||
_multiplier = 1<<multiplier;
|
||||
_poiMultiplier = 1<<poiMultiplier;
|
||||
if (hdrLen >= 0x132) {
|
||||
quint32 offset, size;
|
||||
quint16 recordSize;
|
||||
if (!(seek(hdl, _gmpOffset + 0x124) && readUInt32(hdl, offset)
|
||||
&& readUInt32(hdl, size) && readUInt16(hdl, recordSize)))
|
||||
return false;
|
||||
|
||||
if (size && recordSize) {
|
||||
_table = new quint32[size / recordSize];
|
||||
if (!seek(hdl, offset))
|
||||
return false;
|
||||
for (quint32 i = 0; i < size / recordSize; i++) {
|
||||
if (!readVUInt32(hdl, recordSize, _table[i]))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_encoding == 11) {
|
||||
_huffmanText = new HuffmanText();
|
||||
if (!_huffmanText->load(rgn, rgnHdl))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (codepage == 65001)
|
||||
_codec = QTextCodec::codecForName("UTF-8");
|
||||
@ -82,6 +111,14 @@ bool LBLFile::init(Handle &hdl)
|
||||
return true;
|
||||
}
|
||||
|
||||
void LBLFile::clear()
|
||||
{
|
||||
delete _huffmanText;
|
||||
delete _table;
|
||||
_huffmanText = 0;
|
||||
_table = 0;
|
||||
}
|
||||
|
||||
Label LBLFile::label6b(Handle &hdl, quint32 offset, bool capitalize) const
|
||||
{
|
||||
Label::Shield::Type shieldType = Label::Shield::None;
|
||||
@ -135,20 +172,16 @@ Label LBLFile::label6b(Handle &hdl, quint32 offset, bool capitalize) const
|
||||
}
|
||||
}
|
||||
|
||||
Label LBLFile::label8b(Handle &hdl, quint32 offset, bool capitalize) const
|
||||
Label LBLFile::str2label(const QVector<quint8> &str, bool capitalize) const
|
||||
{
|
||||
Label::Shield::Type shieldType = Label::Shield::None;
|
||||
QByteArray label, shieldLabel;
|
||||
QByteArray *bap = &label;
|
||||
quint8 c;
|
||||
|
||||
if (!seek(hdl, offset))
|
||||
return Label();
|
||||
for (int i = 0; i < str.size(); i++) {
|
||||
const quint8 &c = str.at(i);
|
||||
|
||||
while (true) {
|
||||
if (!readUInt8(hdl, c))
|
||||
return Label();
|
||||
if (!c || c == 0x1d)
|
||||
if (c == 0 || c == 0x1d)
|
||||
break;
|
||||
|
||||
if (c == 0x1c)
|
||||
@ -158,7 +191,7 @@ Label LBLFile::label8b(Handle &hdl, quint32 offset, bool capitalize) const
|
||||
bap = &label;
|
||||
else
|
||||
bap->append(' ');
|
||||
} else if (c <= 0x07) {
|
||||
} else if (c < 0x07) {
|
||||
shieldType = static_cast<Label::Shield::Type>(c);
|
||||
bap = &shieldLabel;
|
||||
} else if (bap == &shieldLabel && c == 0x20) {
|
||||
@ -175,21 +208,74 @@ Label LBLFile::label8b(Handle &hdl, quint32 offset, bool capitalize) const
|
||||
Label::Shield(shieldType, shieldText));
|
||||
}
|
||||
|
||||
Label LBLFile::label(Handle &hdl, quint32 offset, bool poi, bool capitalize)
|
||||
Label LBLFile::label8b(Handle &hdl, quint32 offset, bool capitalize) const
|
||||
{
|
||||
if (!_multiplier && !init(hdl))
|
||||
return QString();
|
||||
QVector<quint8> str;
|
||||
quint8 c;
|
||||
|
||||
if (!seek(hdl, offset))
|
||||
return Label();
|
||||
|
||||
do {
|
||||
if (!readUInt8(hdl, c))
|
||||
return Label();
|
||||
str.append(c);
|
||||
} while (c);
|
||||
|
||||
return str2label(str, capitalize);
|
||||
}
|
||||
|
||||
Label LBLFile::labelHuffman(Handle &hdl, quint32 offset, bool capitalize) const
|
||||
{
|
||||
QVector<quint8> str;
|
||||
|
||||
if (!seek(hdl, offset))
|
||||
return Label();
|
||||
if (!_huffmanText->decode(this, hdl, str))
|
||||
return Label();
|
||||
if (!_table)
|
||||
return str2label(str, capitalize);
|
||||
|
||||
|
||||
QVector<quint8> str2;
|
||||
for (int i = 0; i < str.size(); i++) {
|
||||
quint32 val = _table[str.at(i)];
|
||||
if (val) {
|
||||
if (!seek(hdl, _offset + ((val & 0x7fffff) << _multiplier)))
|
||||
return Label();
|
||||
|
||||
if (str2.size() && str2.back() == '\0')
|
||||
str2[str2.size() - 1] = ' ';
|
||||
else if (str2.size())
|
||||
str2.append(' ');
|
||||
if (!_huffmanText->decode(this, hdl, str2))
|
||||
return Label();
|
||||
} else {
|
||||
if (str.at(i) == 7) {
|
||||
str2.append(0);
|
||||
break;
|
||||
}
|
||||
if (str2.size() && str2.back() == '\0')
|
||||
str2[str2.size() - 1] = ' ';
|
||||
str2.append(str.at(i));
|
||||
}
|
||||
}
|
||||
|
||||
return str2label(str2, capitalize);
|
||||
}
|
||||
|
||||
Label LBLFile::label(Handle &hdl, quint32 offset, bool poi, bool capitalize) const
|
||||
{
|
||||
quint32 labelOffset;
|
||||
if (poi) {
|
||||
quint32 poiOffset;
|
||||
if (!(_poiSize >= offset * _poiMultiplier
|
||||
&& seek(hdl, _poiOffset + offset * _poiMultiplier)
|
||||
if (!(_poiSize >= (offset << _poiMultiplier)
|
||||
&& seek(hdl, _poiOffset + (offset << _poiMultiplier))
|
||||
&& readUInt24(hdl, poiOffset) && (poiOffset & 0x3FFFFF)))
|
||||
return QString();
|
||||
labelOffset = _offset + (poiOffset & 0x3FFFFF) * _multiplier;
|
||||
labelOffset = _offset + ((poiOffset & 0x3FFFFF) << _multiplier);
|
||||
} else
|
||||
labelOffset = _offset + offset * _multiplier;
|
||||
labelOffset = _offset + (offset << _multiplier);
|
||||
|
||||
if (labelOffset > _offset + _size)
|
||||
return QString();
|
||||
@ -200,6 +286,8 @@ Label LBLFile::label(Handle &hdl, quint32 offset, bool poi, bool capitalize)
|
||||
case 9:
|
||||
case 10:
|
||||
return label8b(hdl, labelOffset, capitalize);
|
||||
case 11:
|
||||
return labelHuffman(hdl, labelOffset, capitalize);
|
||||
default:
|
||||
return Label();
|
||||
}
|
||||
|
@ -5,28 +5,40 @@
|
||||
#include "label.h"
|
||||
|
||||
class QTextCodec;
|
||||
class HuffmanText;
|
||||
class RGNFile;
|
||||
|
||||
class LBLFile : public SubFile
|
||||
{
|
||||
public:
|
||||
LBLFile(IMG *img)
|
||||
: SubFile(img), _codec(0), _offset(0), _size(0), _poiOffset(0),
|
||||
_poiSize(0), _poiMultiplier(0), _multiplier(0), _encoding(0) {}
|
||||
LBLFile(const QString &path)
|
||||
: SubFile(path), _codec(0), _offset(0), _size(0), _poiOffset(0),
|
||||
_poiSize(0), _poiMultiplier(0), _multiplier(0), _encoding(0) {}
|
||||
: SubFile(img), _huffmanText(0), _table(0), _codec(0), _offset(0),
|
||||
_size(0), _poiOffset(0), _poiSize(0), _poiMultiplier(0), _multiplier(0),
|
||||
_encoding(0) {}
|
||||
LBLFile(const QString *path)
|
||||
: SubFile(path), _huffmanText(0), _table(0), _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) {}
|
||||
_huffmanText(0), _table(0), _codec(0), _offset(0), _size(0),
|
||||
_poiOffset(0), _poiSize(0), _poiMultiplier(0), _multiplier(0),
|
||||
_encoding(0) {}
|
||||
~LBLFile();
|
||||
|
||||
bool load(Handle &hdl, const RGNFile *rgn, Handle &rgnHdl);
|
||||
void clear();
|
||||
|
||||
Label label(Handle &hdl, quint32 offset, bool poi = false,
|
||||
bool capitalize = true);
|
||||
bool capitalize = true) const;
|
||||
|
||||
private:
|
||||
bool init(Handle &hdl);
|
||||
|
||||
Label str2label(const QVector<quint8> &str, bool capitalize) const;
|
||||
Label label6b(Handle &hdl, quint32 offset, bool capitalize) const;
|
||||
Label label8b(Handle &hdl, quint32 offset, bool capitalize) const;
|
||||
Label labelHuffman(Handle &hdl, quint32 offset, bool capitalize) const;
|
||||
|
||||
HuffmanText *_huffmanText;
|
||||
quint32 *_table;
|
||||
|
||||
QTextCodec *_codec;
|
||||
quint32 _offset;
|
||||
|
@ -107,7 +107,7 @@ void MapData::load()
|
||||
else {
|
||||
QString typFile(ProgramPaths::typFile());
|
||||
if (!typFile.isEmpty()) {
|
||||
SubFile typ(typFile);
|
||||
SubFile typ(&typFile);
|
||||
_style = new Style(&typ);
|
||||
} else
|
||||
_style = new Style();
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "subdiv.h"
|
||||
#include "nodfile.h"
|
||||
#include "lblfile.h"
|
||||
#include "rgnfile.h"
|
||||
#include "netfile.h"
|
||||
|
||||
|
||||
@ -93,7 +94,7 @@ static bool seekToLine(BitStream4R &bs, quint8 line)
|
||||
}
|
||||
|
||||
static bool readLine(BitStream4R &bs, const SubDiv *subdiv,
|
||||
const HuffmanTable &table, IMG::Poly &poly)
|
||||
const HuffmanTable *table, MapData::Poly &poly)
|
||||
{
|
||||
quint32 v1, v2, v2b;
|
||||
if (!bs.readVuint32SM(v1, v2, v2b))
|
||||
@ -113,7 +114,7 @@ static bool readLine(BitStream4R &bs, const SubDiv *subdiv,
|
||||
poly.boundingRect = RectC(c, c);
|
||||
poly.points.append(QPointF(c.lon(), c.lat()));
|
||||
|
||||
HuffmanStreamR stream(bs, table);
|
||||
HuffmanStreamR stream(bs, *table);
|
||||
if (!stream.init())
|
||||
return false;
|
||||
qint32 lonDelta, latDelta;
|
||||
@ -132,8 +133,8 @@ static bool readLine(BitStream4R &bs, const SubDiv *subdiv,
|
||||
return stream.atEnd();
|
||||
}
|
||||
|
||||
static bool readNodeGeometry(NODFile *nod, SubFile::Handle &nodHdl,
|
||||
NODFile::AdjacencyInfo &adj, IMG::Poly &poly, quint16 cnt = 0xFFFF)
|
||||
static bool readNodeGeometry(const NODFile *nod, SubFile::Handle &nodHdl,
|
||||
NODFile::AdjacencyInfo &adj, MapData::Poly &poly, quint16 cnt = 0xFFFF)
|
||||
{
|
||||
for (int i = 0; i <= cnt; i++) {
|
||||
int ret = nod->nextNode(nodHdl, adj);
|
||||
@ -151,7 +152,7 @@ static bool readNodeGeometry(NODFile *nod, SubFile::Handle &nodHdl,
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool skipNodes(NODFile *nod, SubFile::Handle &nodHdl,
|
||||
static bool skipNodes(const NODFile *nod, SubFile::Handle &nodHdl,
|
||||
NODFile::AdjacencyInfo &adj, int cnt)
|
||||
{
|
||||
for (int i = 0; i < cnt; i++)
|
||||
@ -161,10 +162,10 @@ static bool skipNodes(NODFile *nod, SubFile::Handle &nodHdl,
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool readShape(NODFile *nod, SubFile::Handle &nodHdl,
|
||||
NODFile::AdjacencyInfo &adj, BitStream4R &bs, const HuffmanTable &table,
|
||||
const SubDiv *subdiv, quint32 shift, IMG::Poly &poly, quint16 cnt = 0xFFFF,
|
||||
bool check = false)
|
||||
static bool readShape(const NODFile *nod, SubFile::Handle &nodHdl,
|
||||
NODFile::AdjacencyInfo &adj, BitStream4R &bs, const HuffmanTable *table,
|
||||
const SubDiv *subdiv, quint32 shift, MapData::Poly &poly,
|
||||
quint16 cnt = 0xFFFF, bool check = false)
|
||||
{
|
||||
quint32 v1, v2, v2b;
|
||||
if (!bs.readVuint32SM(v1, v2, v2b))
|
||||
@ -233,7 +234,7 @@ static bool readShape(NODFile *nod, SubFile::Handle &nodHdl,
|
||||
}
|
||||
}
|
||||
|
||||
HuffmanStreamR stream(bs, table);
|
||||
HuffmanStreamR stream(bs, *table);
|
||||
if (!stream.init(lonSign, latSign, flags, extraBits))
|
||||
return false;
|
||||
qint32 lonDelta, latDelta;
|
||||
@ -345,8 +346,13 @@ static bool readShape(NODFile *nod, SubFile::Handle &nodHdl,
|
||||
}
|
||||
|
||||
|
||||
bool NETFile::linkLabel(Handle &hdl, quint32 offset, quint32 size, LBLFile *lbl,
|
||||
Handle &lblHdl, Label &label)
|
||||
NETFile::~NETFile()
|
||||
{
|
||||
delete _huffmanTable;
|
||||
}
|
||||
|
||||
bool NETFile::linkLabel(Handle &hdl, quint32 offset, quint32 size,
|
||||
const LBLFile *lbl, Handle &lblHdl, Label &label) const
|
||||
{
|
||||
if (!seek(hdl, offset))
|
||||
return false;
|
||||
@ -360,19 +366,13 @@ bool NETFile::linkLabel(Handle &hdl, quint32 offset, quint32 size, LBLFile *lbl,
|
||||
|
||||
if (!bs.readUInt24(labelPtr))
|
||||
return false;
|
||||
if (labelPtr & 0x3FFFFF) {
|
||||
if (labelPtr & 0x400000) {
|
||||
quint32 lblOff;
|
||||
if (lblOffset(hdl, labelPtr & 0x3FFFFF, lblOff) && lblOff)
|
||||
label = lbl->label(lblHdl, lblOff);
|
||||
} else
|
||||
if (labelPtr & 0x3FFFFF)
|
||||
label = lbl->label(lblHdl, labelPtr & 0x3FFFFF);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NETFile::init(Handle &hdl)
|
||||
bool NETFile::load(Handle &hdl, const RGNFile *rgn, Handle &rgnHdl)
|
||||
{
|
||||
quint16 hdrLen;
|
||||
|
||||
@ -385,31 +385,36 @@ bool NETFile::init(Handle &hdl)
|
||||
quint32 info;
|
||||
if (!(seek(hdl, _gmpOffset + 0x37) && readUInt32(hdl, info)))
|
||||
return false;
|
||||
_tableId = ((info >> 2) & 0xF);
|
||||
|
||||
if (!(seek(hdl, _gmpOffset + 0x43) && readUInt32(hdl, _linksOffset)
|
||||
&& readUInt32(hdl, _linksSize) && readUInt8(hdl, _linksShift)))
|
||||
return false;
|
||||
|
||||
quint8 tableId = ((info >> 2) & 0xF);
|
||||
if (_linksSize && (!rgn->huffmanTable() || rgn->huffmanTable()->id()
|
||||
!= tableId)) {
|
||||
_huffmanTable = new HuffmanTable(tableId);
|
||||
if (!_huffmanTable->load(rgn, rgnHdl))
|
||||
return false;
|
||||
}
|
||||
|
||||
_init = true;
|
||||
_tp = _huffmanTable ? _huffmanTable : rgn->huffmanTable();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NETFile::link(const SubDiv *subdiv, quint32 shift, Handle &hdl,
|
||||
NODFile *nod, Handle &nodHdl, LBLFile *lbl, Handle &lblHdl,
|
||||
const NODFile::BlockInfo &blockInfo, quint8 linkId, quint8 lineId,
|
||||
const HuffmanTable &table, QList<IMG::Poly> *lines)
|
||||
void NETFile::clear()
|
||||
{
|
||||
if (!_init && !init(hdl))
|
||||
return false;
|
||||
delete _huffmanTable;
|
||||
_huffmanTable = 0;
|
||||
}
|
||||
|
||||
Q_ASSERT(_tableId == table.id());
|
||||
if (_tableId != table.id())
|
||||
return false;
|
||||
|
||||
IMG::Poly poly;
|
||||
bool NETFile::link(const SubDiv *subdiv, quint32 shift, Handle &hdl,
|
||||
const NODFile *nod, Handle &nodHdl, const LBLFile *lbl, Handle &lblHdl,
|
||||
const NODFile::BlockInfo &blockInfo, quint8 linkId, quint8 lineId,
|
||||
QList<MapData::Poly> *lines) const
|
||||
{
|
||||
MapData::Poly poly;
|
||||
if (!nod->linkType(nodHdl, blockInfo, linkId, poly.type))
|
||||
return false;
|
||||
|
||||
@ -445,7 +450,7 @@ bool NETFile::link(const SubDiv *subdiv, quint32 shift, Handle &hdl,
|
||||
|
||||
if (s69 == 1) {
|
||||
if (s68 == 1) {
|
||||
if (!readShape(nod, nodHdl, adj, bs, table, subdiv, shift, poly))
|
||||
if (!readShape(nod, nodHdl, adj, bs, _tp, subdiv, shift, poly))
|
||||
return false;
|
||||
} else {
|
||||
if (!readNodeGeometry(nod, nodHdl, adj, poly))
|
||||
@ -459,7 +464,7 @@ bool NETFile::link(const SubDiv *subdiv, quint32 shift, Handle &hdl,
|
||||
if (i == lineId) {
|
||||
if (shape) {
|
||||
bool check = (i < ca.size()) ? (ca.at(i) & mask) : false;
|
||||
if (!readShape(nod, nodHdl, adj, bs, table, subdiv,
|
||||
if (!readShape(nod, nodHdl, adj, bs, _tp, subdiv,
|
||||
shift, poly, step, check))
|
||||
return false;
|
||||
} else {
|
||||
@ -483,7 +488,7 @@ bool NETFile::link(const SubDiv *subdiv, quint32 shift, Handle &hdl,
|
||||
return false;
|
||||
if (!seekToLine(bs, lineId))
|
||||
return false;
|
||||
if (!readLine(bs, subdiv, table, poly))
|
||||
if (!readLine(bs, subdiv, _tp, poly))
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -496,11 +501,8 @@ bool NETFile::link(const SubDiv *subdiv, quint32 shift, Handle &hdl,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NETFile::lblOffset(Handle &hdl, quint32 netOffset, quint32 &lblOffset)
|
||||
bool NETFile::lblOffset(Handle &hdl, quint32 netOffset, quint32 &lblOffset) const
|
||||
{
|
||||
if (!_init && !init(hdl))
|
||||
return false;
|
||||
|
||||
if (!(seek(hdl, _offset + (netOffset << _shift))
|
||||
&& readUInt24(hdl, lblOffset)))
|
||||
return false;
|
||||
|
@ -1,42 +1,44 @@
|
||||
#ifndef NETFILE_H
|
||||
#define NETFILE_H
|
||||
|
||||
#include "img.h"
|
||||
#include "subfile.h"
|
||||
#include "nodfile.h"
|
||||
|
||||
class NODFile;
|
||||
class LBLFile;
|
||||
class RGNFile;
|
||||
class SubDiv;
|
||||
class HuffmanTable;
|
||||
|
||||
class NETFile : public SubFile
|
||||
{
|
||||
public:
|
||||
NETFile(IMG *img) : SubFile(img), _offset(0), _size(0), _linksOffset(0),
|
||||
_linksSize(0), _shift(0), _linksShift(0), _init(false) {}
|
||||
NETFile(const QString &path) : SubFile(path), _offset(0), _size(0),
|
||||
_linksOffset(0), _linksSize(0), _shift(0), _linksShift(0),
|
||||
_init(false) {}
|
||||
NETFile(SubFile *gmp, quint32 offset) : SubFile(gmp, offset),
|
||||
NETFile(IMG *img) : SubFile(img), _huffmanTable(0), _tp(0), _offset(0),
|
||||
_size(0), _linksOffset(0), _linksSize(0), _shift(0), _linksShift(0) {}
|
||||
NETFile(const QString *path) : SubFile(path), _huffmanTable(0), _tp(0),
|
||||
_offset(0), _size(0), _linksOffset(0), _linksSize(0), _shift(0),
|
||||
_linksShift(0), _init(false) {}
|
||||
_linksShift(0) {}
|
||||
NETFile(SubFile *gmp, quint32 offset) : SubFile(gmp, offset),
|
||||
_huffmanTable(0), _tp(0), _offset(0), _size(0), _linksOffset(0),
|
||||
_linksSize(0), _shift(0), _linksShift(0) {}
|
||||
~NETFile();
|
||||
|
||||
bool lblOffset(Handle &hdl, quint32 netOffset, quint32 &lblOffset);
|
||||
bool link(const SubDiv *subdiv, quint32 shift, Handle &hdl, NODFile *nod,
|
||||
Handle &nodHdl, LBLFile *lbl, Handle &lblHdl,
|
||||
bool load(Handle &hdl, const RGNFile *rgn, Handle &rgnHdl);
|
||||
void clear();
|
||||
|
||||
bool lblOffset(Handle &hdl, quint32 netOffset, quint32 &lblOffset) const;
|
||||
bool link(const SubDiv *subdiv, quint32 shift, Handle &hdl,
|
||||
const NODFile *nod, Handle &nodHdl, const LBLFile *lbl, Handle &lblHdl,
|
||||
const NODFile::BlockInfo &blockInfo, quint8 linkId, quint8 lineId,
|
||||
const HuffmanTable &table, QList<IMG::Poly> *lines);
|
||||
QList<MapData::Poly> *lines) const;
|
||||
|
||||
private:
|
||||
bool init(Handle &hdl);
|
||||
bool linkLabel(Handle &hdl, quint32 offset, quint32 size, LBLFile *lbl,
|
||||
Handle &lblHdl, Label &label);
|
||||
bool linkLabel(Handle &hdl, quint32 offset, quint32 size,
|
||||
const LBLFile *lbl, Handle &lblHdl, Label &label) const;
|
||||
|
||||
HuffmanTable *_huffmanTable;
|
||||
const HuffmanTable *_tp;
|
||||
quint32 _offset, _size, _linksOffset, _linksSize;
|
||||
quint8 _shift, _linksShift;
|
||||
quint8 _tableId;
|
||||
bool _init;
|
||||
};
|
||||
|
||||
#endif // NETFILE_H
|
||||
|
@ -81,14 +81,14 @@ static bool skipOptAdjData(BitStream1 &bs)
|
||||
}
|
||||
|
||||
|
||||
bool NODFile::init(Handle &hdl)
|
||||
bool NODFile::load(Handle &hdl)
|
||||
{
|
||||
quint16 hdrLen;
|
||||
|
||||
if (!(seek(hdl, _gmpOffset) && readUInt16(hdl, hdrLen)))
|
||||
return false;
|
||||
if (hdrLen < 0x7b)
|
||||
return false;
|
||||
return true;
|
||||
|
||||
if (!(seek(hdl, _gmpOffset + 0x1d) && readUInt32(hdl, _flags)
|
||||
&& readUInt8(hdl, _blockShift) && readUInt8(hdl, _nodeShift)))
|
||||
@ -113,14 +113,6 @@ bool NODFile::init(Handle &hdl)
|
||||
return (_indexIdSize > 0);
|
||||
}
|
||||
|
||||
quint32 NODFile::indexIdSize(Handle &hdl)
|
||||
{
|
||||
if (!_indexIdSize && !init(hdl))
|
||||
return 0;
|
||||
|
||||
return _indexIdSize;
|
||||
}
|
||||
|
||||
bool NODFile::readBlock(Handle &hdl, quint32 blockOffset,
|
||||
BlockInfo &blockInfo) const
|
||||
{
|
||||
@ -494,7 +486,7 @@ bool NODFile::relAdjInfo(Handle &hdl, AdjacencyInfo &adj) const
|
||||
return true;
|
||||
}
|
||||
|
||||
int NODFile::nextNode(Handle &hdl, AdjacencyInfo &adjInfo)
|
||||
int NODFile::nextNode(Handle &hdl, AdjacencyInfo &adjInfo) const
|
||||
{
|
||||
if (adjInfo.nodeOffset == 0xFFFFFFFF)
|
||||
return 1;
|
||||
|
@ -1,7 +1,6 @@
|
||||
#ifndef NODFILE_H
|
||||
#define NODFILE_H
|
||||
|
||||
#include "img.h"
|
||||
#include "subfile.h"
|
||||
|
||||
class NODFile : public SubFile
|
||||
@ -57,7 +56,7 @@ public:
|
||||
NODFile(IMG *img) : SubFile(img), _indexOffset(0), _indexSize(0),
|
||||
_indexFlags(0), _blockOffset(0), _blockSize(0), _indexRecordSize(0),
|
||||
_blockRecordSize(0), _blockShift(0), _nodeShift(0), _indexIdSize(0) {}
|
||||
NODFile(const QString &path) : SubFile(path), _indexOffset(0), _indexSize(0),
|
||||
NODFile(const QString *path) : SubFile(path), _indexOffset(0), _indexSize(0),
|
||||
_indexFlags(0), _blockOffset(0), _blockSize(0), _indexRecordSize(0),
|
||||
_blockRecordSize(0), _blockShift(0), _nodeShift(0), _indexIdSize(0) {}
|
||||
NODFile(SubFile *gmp, quint32 offset) : SubFile(gmp, offset),
|
||||
@ -65,16 +64,17 @@ public:
|
||||
_blockSize(0), _indexRecordSize(0), _blockRecordSize(0), _blockShift(0),
|
||||
_nodeShift(0), _indexIdSize(0) {}
|
||||
|
||||
quint32 indexIdSize(Handle &hdl);
|
||||
bool load(Handle &hdl);
|
||||
|
||||
quint32 indexIdSize() const {return _indexIdSize;}
|
||||
bool blockInfo(Handle &hdl, quint32 blockId, BlockInfo &blockInfo) const;
|
||||
bool linkInfo(Handle &hdl, const BlockInfo &blockInfo, quint32 linkId,
|
||||
LinkInfo &linkInfo) const;
|
||||
bool linkType(Handle &hdl, const BlockInfo &blockInfo, quint8 linkId,
|
||||
quint32 &type) const;
|
||||
int nextNode(Handle &hdl, AdjacencyInfo &adjInfo);
|
||||
int nextNode(Handle &hdl, AdjacencyInfo &adjInfo) const;
|
||||
|
||||
private:
|
||||
bool init(Handle &hdl);
|
||||
bool nodeInfo(Handle &hdl, const BlockInfo &blockInfo, quint32 nodeOffset,
|
||||
NodeInfo &nodeInfo) const;
|
||||
bool nodeOffset(Handle &hdl, const BlockInfo &blockInfo, quint8 nodeId,
|
||||
|
@ -24,6 +24,11 @@ static quint64 pointId(const QPoint &pos, quint32 type, quint32 labelPtr)
|
||||
return id;
|
||||
}
|
||||
|
||||
RGNFile::~RGNFile()
|
||||
{
|
||||
delete _huffmanTable;
|
||||
}
|
||||
|
||||
bool RGNFile::skipClassFields(Handle &hdl) const
|
||||
{
|
||||
quint8 flags;
|
||||
@ -96,7 +101,7 @@ bool RGNFile::skipGblFields(Handle &hdl, quint32 flags) const
|
||||
return seek(hdl, pos(hdl) + cnt);
|
||||
}
|
||||
|
||||
bool RGNFile::init(Handle &hdl)
|
||||
bool RGNFile::load(Handle &hdl)
|
||||
{
|
||||
quint16 hdrLen;
|
||||
|
||||
@ -125,24 +130,29 @@ bool RGNFile::init(Handle &hdl)
|
||||
}
|
||||
|
||||
if (hdrLen >= 0x7D) {
|
||||
quint32 dictOffset, dictSize, info;
|
||||
if (!(seek(hdl, _gmpOffset + 0x71) && readUInt32(hdl, dictOffset)
|
||||
&& readUInt32(hdl, dictSize) && readUInt32(hdl, info)))
|
||||
quint32 info;
|
||||
if (!(seek(hdl, _gmpOffset + 0x71) && readUInt32(hdl, _dictOffset)
|
||||
&& readUInt32(hdl, _dictSize) && readUInt32(hdl, info)))
|
||||
return false;
|
||||
|
||||
if (dictSize && dictOffset && (info & 0x1E))
|
||||
if (!_huffmanTable.load(*this, hdl, dictOffset, dictSize,
|
||||
((info >> 1) & 0xF) - 1))
|
||||
if (_dictSize && _dictOffset && (info & 0x1E)) {
|
||||
_huffmanTable = new HuffmanTable(((info >> 1) & 0xF) - 1);
|
||||
if (!_huffmanTable->load(this, hdl))
|
||||
return false;
|
||||
}
|
||||
|
||||
_init = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void RGNFile::clear()
|
||||
{
|
||||
delete _huffmanTable;
|
||||
_huffmanTable = 0;
|
||||
}
|
||||
|
||||
bool RGNFile::polyObjects(Handle &hdl, const SubDiv *subdiv,
|
||||
SegmentType segmentType, LBLFile *lbl, Handle &lblHdl, NETFile *net,
|
||||
SegmentType segmentType, const LBLFile *lbl, Handle &lblHdl, NETFile *net,
|
||||
Handle &netHdl, QList<IMG::Poly> *polys) const
|
||||
{
|
||||
const SubDiv::Segment &segment = (segmentType == Line)
|
||||
@ -218,7 +228,7 @@ bool RGNFile::polyObjects(Handle &hdl, const SubDiv *subdiv,
|
||||
}
|
||||
|
||||
bool RGNFile::extPolyObjects(Handle &hdl, const SubDiv *subdiv, quint32 shift,
|
||||
SegmentType segmentType, LBLFile *lbl, Handle &lblHdl,
|
||||
SegmentType segmentType, const LBLFile *lbl, Handle &lblHdl,
|
||||
QList<IMG::Poly> *polys) const
|
||||
{
|
||||
quint32 labelPtr, len;
|
||||
@ -246,13 +256,13 @@ bool RGNFile::extPolyObjects(Handle &hdl, const SubDiv *subdiv, quint32 shift,
|
||||
poly.type = 0x10000 | (quint16(type)<<8) | (subtype & 0x1F);
|
||||
labelPtr = 0;
|
||||
|
||||
if (!_huffmanTable.isNull()) {
|
||||
if (_huffmanTable) {
|
||||
pos = QPoint(LS(subdiv->lon(), 8) + LS(lon, 32-subdiv->bits()),
|
||||
LS(subdiv->lat(), 8) + LS(lat, (32-subdiv->bits())));
|
||||
|
||||
qint32 lonDelta, latDelta;
|
||||
BitStream4F bs(*this, hdl, len);
|
||||
HuffmanStreamF stream(bs, _huffmanTable);
|
||||
HuffmanStreamF stream(bs, *_huffmanTable);
|
||||
if (!stream.init(segmentType == Line))
|
||||
return false;
|
||||
|
||||
@ -329,7 +339,7 @@ bool RGNFile::extPolyObjects(Handle &hdl, const SubDiv *subdiv, quint32 shift,
|
||||
}
|
||||
|
||||
bool RGNFile::pointObjects(Handle &hdl, const SubDiv *subdiv,
|
||||
SegmentType segmentType, LBLFile *lbl, Handle &lblHdl,
|
||||
SegmentType segmentType, const LBLFile *lbl, Handle &lblHdl,
|
||||
QList<IMG::Point> *points) const
|
||||
{
|
||||
const SubDiv::Segment &segment = (segmentType == IndexedPoint)
|
||||
@ -363,9 +373,8 @@ bool RGNFile::pointObjects(Handle &hdl, const SubDiv *subdiv,
|
||||
point.coordinates = Coordinates(toWGS24(pos.x()), toWGS24(pos.y()));
|
||||
point.id = pointId(pos, point.type, labelPtr & 0x3FFFFF);
|
||||
if (lbl && (labelPtr & 0x3FFFFF))
|
||||
point.label = lbl->label(lblHdl, labelPtr & 0x3FFFFF,
|
||||
labelPtr & 0x400000, !(point.type == 0x1400 || point.type == 0x1500
|
||||
|| point.type == 0x1e00));
|
||||
point.label = lbl->label(lblHdl, labelPtr & 0x3FFFFF, labelPtr & 0x400000,
|
||||
!(point.type == 0x1400 || point.type == 0x1500 || point.type == 0x1e00));
|
||||
|
||||
points->append(point);
|
||||
}
|
||||
@ -373,11 +382,12 @@ bool RGNFile::pointObjects(Handle &hdl, const SubDiv *subdiv,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RGNFile::extPointObjects(Handle &hdl, const SubDiv *subdiv, LBLFile *lbl,
|
||||
Handle &lblHdl, QList<IMG::Point> *points) const
|
||||
bool RGNFile::extPointObjects(Handle &hdl, const SubDiv *subdiv,
|
||||
const LBLFile *lbl, Handle &lblHdl, QList<IMG::Point> *points) const
|
||||
{
|
||||
const SubDiv::Segment &segment = subdiv->extPoints();
|
||||
|
||||
|
||||
if (!segment.isValid())
|
||||
return true;
|
||||
if (!seek(hdl, segment.offset()))
|
||||
@ -423,30 +433,27 @@ bool RGNFile::extPointObjects(Handle &hdl, const SubDiv *subdiv, LBLFile *lbl,
|
||||
}
|
||||
|
||||
bool RGNFile::links(Handle &hdl, const SubDiv *subdiv, quint32 shift,
|
||||
NETFile *net, Handle &netHdl, NODFile *nod, Handle &nodHdl, LBLFile *lbl,
|
||||
Handle &lblHdl, QList<IMG::Poly> *lines) const
|
||||
const NETFile *net, Handle &netHdl, const NODFile *nod, Handle &nodHdl,
|
||||
const LBLFile *lbl, Handle &lblHdl, QList<IMG::Poly> *lines) const
|
||||
{
|
||||
quint32 size, blockIndexIdSize, blockIndexId;
|
||||
quint32 size, blockIndexId;
|
||||
quint8 flags;
|
||||
const SubDiv::Segment &segment = subdiv->roadReferences();
|
||||
|
||||
if (!net || !nod)
|
||||
return false;
|
||||
if (!segment.isValid())
|
||||
return true;
|
||||
if (!seek(hdl, segment.offset()))
|
||||
return false;
|
||||
|
||||
if (!net || !nod)
|
||||
return false;
|
||||
if (!(blockIndexIdSize = nod->indexIdSize(nodHdl)))
|
||||
return false;
|
||||
|
||||
while (pos(hdl) < segment.end()) {
|
||||
if (!readVUInt32(hdl, size))
|
||||
return false;
|
||||
|
||||
quint32 entryStart = pos(hdl);
|
||||
|
||||
if (!(readUInt8(hdl, flags) && readVUInt32(hdl, blockIndexIdSize,
|
||||
if (!(readUInt8(hdl, flags) && readVUInt32(hdl, nod->indexIdSize(),
|
||||
blockIndexId)))
|
||||
return false;
|
||||
|
||||
@ -494,10 +501,11 @@ bool RGNFile::links(Handle &hdl, const SubDiv *subdiv, quint32 shift,
|
||||
}
|
||||
|
||||
net->link(subdiv, shift, netHdl, nod, nodHdl, lbl, lblHdl,
|
||||
blockInfo, linkId, lineId, _huffmanTable, lines);
|
||||
blockInfo, linkId, lineId, lines);
|
||||
}
|
||||
|
||||
Q_ASSERT(entryStart + size == pos(hdl));
|
||||
if (entryStart + size != pos(hdl))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -546,7 +554,7 @@ QMap<RGNFile::SegmentType, SubDiv::Segment> RGNFile::segments(Handle &hdl,
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool RGNFile::subdivInit(Handle &hdl, SubDiv *subdiv) const
|
||||
bool RGNFile::subdivInit(Handle &hdl, SubDiv *subdiv)
|
||||
{
|
||||
QMap<RGNFile::SegmentType, SubDiv::Segment> seg(segments(hdl, subdiv));
|
||||
SubDiv::Segment extPoints, extLines, extPolygons;
|
||||
|
@ -1,14 +1,13 @@
|
||||
#ifndef RGNFILE_H
|
||||
#define RGNFILE_H
|
||||
|
||||
#include "img.h"
|
||||
#include "subfile.h"
|
||||
#include "subdiv.h"
|
||||
#include "huffmantable.h"
|
||||
|
||||
class LBLFile;
|
||||
class NETFile;
|
||||
class NODFile;
|
||||
class HuffmanTable;
|
||||
|
||||
class RGNFile : public SubFile
|
||||
{
|
||||
@ -22,35 +21,41 @@ public:
|
||||
};
|
||||
|
||||
RGNFile(IMG *img)
|
||||
: SubFile(img), _offset(0), _size(0), _polygonsOffset(0),
|
||||
: SubFile(img), _huffmanTable(0), _offset(0), _size(0), _polygonsOffset(0),
|
||||
_polygonsSize(0), _linesOffset(0), _linesSize(0), _pointsOffset(0),
|
||||
_pointsSize(0), _init(false) {}
|
||||
RGNFile(const QString &path)
|
||||
: SubFile(path), _offset(0), _size(0), _polygonsOffset(0),
|
||||
_pointsSize(0) {}
|
||||
RGNFile(const QString *path)
|
||||
: SubFile(path), _huffmanTable(0), _offset(0), _size(0), _polygonsOffset(0),
|
||||
_polygonsSize(0), _linesOffset(0), _linesSize(0), _pointsOffset(0),
|
||||
_pointsSize(0), _init(false) {}
|
||||
RGNFile(SubFile *gmp, quint32 offset) : SubFile(gmp, offset), _offset(0),
|
||||
_size(0), _polygonsOffset(0), _polygonsSize(0), _linesOffset(0),
|
||||
_linesSize(0), _pointsOffset(0), _pointsSize(0), _init(false) {}
|
||||
_pointsSize(0) {}
|
||||
RGNFile(SubFile *gmp, quint32 offset) : SubFile(gmp, offset),
|
||||
_huffmanTable(0), _offset(0), _size(0), _polygonsOffset(0),
|
||||
_polygonsSize(0), _linesOffset(0), _linesSize(0), _pointsOffset(0),
|
||||
_pointsSize(0) {}
|
||||
~RGNFile();
|
||||
|
||||
bool initialized() const {return _init;}
|
||||
bool init(Handle &hdl);
|
||||
void clear();
|
||||
bool load(Handle &hdl);
|
||||
|
||||
bool polyObjects(Handle &hdl, const SubDiv *subdiv, SegmentType segmentType,
|
||||
LBLFile *lbl, Handle &lblHdl, NETFile *net, Handle &netHdl,
|
||||
QList<IMG::Poly> *polys) const;
|
||||
const LBLFile *lbl, Handle &lblHdl, NETFile *net, Handle &netHdl,
|
||||
QList<MapData::Poly> *polys) const;
|
||||
bool pointObjects(Handle &hdl, const SubDiv *subdiv, SegmentType segmentType,
|
||||
LBLFile *lbl, Handle &lblHdl, QList<IMG::Point> *points) const;
|
||||
const LBLFile *lbl, Handle &lblHdl, QList<MapData::Point> *points) const;
|
||||
bool extPolyObjects(Handle &hdl, const SubDiv *subdiv, quint32 shift,
|
||||
SegmentType segmentType, LBLFile *lbl, Handle &lblHdl,
|
||||
QList<IMG::Poly> *polys) const;
|
||||
bool extPointObjects(Handle &hdl, const SubDiv *subdiv, LBLFile *lbl,
|
||||
Handle &lblHdl, QList<IMG::Point> *points) const;
|
||||
bool links(Handle &hdl, const SubDiv *subdiv, quint32 shift, NETFile *net,
|
||||
Handle &netHdl, NODFile *nod, Handle &nodHdl, LBLFile *lbl, Handle &lblHdl,
|
||||
QList<IMG::Poly> *lines) const;
|
||||
SegmentType segmentType, const LBLFile *lbl, Handle &lblHdl,
|
||||
QList<MapData::Poly> *polys) const;
|
||||
bool extPointObjects(Handle &hdl, const SubDiv *subdiv, const LBLFile *lbl,
|
||||
Handle &lblHdl, QList<MapData::Point> *points) const;
|
||||
bool links(Handle &hdl, const SubDiv *subdiv, quint32 shift,
|
||||
const NETFile *net, Handle &netHdl, const NODFile *nod, Handle &nodHdl,
|
||||
const LBLFile *lbl, Handle &lblHdl, QList<MapData::Poly> *lines) const;
|
||||
|
||||
bool subdivInit(Handle &hdl, SubDiv *subdiv) const;
|
||||
bool subdivInit(Handle &hdl, SubDiv *subdiv);
|
||||
|
||||
const HuffmanTable *huffmanTable() const {return _huffmanTable;}
|
||||
quint32 dictOffset() const {return _dictOffset;}
|
||||
quint32 dictSize() const {return _dictSize;}
|
||||
|
||||
private:
|
||||
QMap<SegmentType, SubDiv::Segment> segments(Handle &hdl, SubDiv *subdiv)
|
||||
@ -60,8 +65,12 @@ private:
|
||||
const;
|
||||
bool skipGblFields(Handle &hdl, quint32 flags) const;
|
||||
|
||||
HuffmanTable *_huffmanTable;
|
||||
|
||||
quint32 _offset;
|
||||
quint32 _size;
|
||||
quint32 _dictOffset;
|
||||
quint32 _dictSize;
|
||||
|
||||
quint32 _polygonsOffset;
|
||||
quint32 _polygonsSize;
|
||||
@ -75,10 +84,6 @@ private:
|
||||
quint32 _pointsSize;
|
||||
quint32 _pointsLclFlags[3];
|
||||
quint32 _pointsGblFlags;
|
||||
|
||||
HuffmanTable _huffmanTable;
|
||||
|
||||
bool _init;
|
||||
};
|
||||
|
||||
#endif // RGNFILE_H
|
||||
|
@ -42,14 +42,12 @@ public:
|
||||
: _gmpOffset(0), _img(img), _blocks(new QVector<quint16>()), _path(0) {}
|
||||
SubFile(SubFile *gmp, quint32 offset) : _gmpOffset(offset), _img(gmp->_img),
|
||||
_blocks(gmp->_blocks), _path(gmp->_path) {}
|
||||
SubFile(const QString &path)
|
||||
: _gmpOffset(0), _img(0), _blocks(0), _path(new QString(path)) {}
|
||||
SubFile(const QString *path)
|
||||
: _gmpOffset(0), _img(0), _blocks(0), _path(path) {}
|
||||
~SubFile()
|
||||
{
|
||||
if (!_gmpOffset) {
|
||||
if (!_gmpOffset)
|
||||
delete _blocks;
|
||||
delete _path;
|
||||
}
|
||||
}
|
||||
|
||||
void addBlock(quint16 block) {_blocks->append(block);}
|
||||
@ -151,7 +149,7 @@ private:
|
||||
|
||||
IMG *_img;
|
||||
QVector<quint16> *_blocks;
|
||||
QString *_path;
|
||||
const QString *_path;
|
||||
};
|
||||
|
||||
#endif // SUBFILE_H
|
||||
|
@ -14,7 +14,7 @@ class TREFile : public SubFile
|
||||
{
|
||||
public:
|
||||
TREFile(IMG *img) : SubFile(img) {}
|
||||
TREFile(const QString &path) : SubFile(path) {}
|
||||
TREFile(const QString *path) : SubFile(path) {}
|
||||
TREFile(SubFile *gmp, quint32 offset) : SubFile(gmp, offset) {}
|
||||
~TREFile();
|
||||
|
||||
|
@ -1,16 +1,16 @@
|
||||
#include "vectortile.h"
|
||||
|
||||
|
||||
static void copyPolys(const RectC &rect, QList<IMG::Poly> *src,
|
||||
QList<IMG::Poly> *dst)
|
||||
static void copyPolys(const RectC &rect, QList<MapData::Poly> *src,
|
||||
QList<MapData::Poly> *dst)
|
||||
{
|
||||
for (int i = 0; i < src->size(); i++)
|
||||
if (rect.intersects(src->at(i).boundingRect))
|
||||
dst->append(src->at(i));
|
||||
}
|
||||
|
||||
static void copyPoints(const RectC &rect, QList<IMG::Point> *src,
|
||||
QList<IMG::Point> *dst)
|
||||
static void copyPoints(const RectC &rect, QList<MapData::Point> *src,
|
||||
QList<MapData::Point> *dst)
|
||||
{
|
||||
for (int j = 0; j < src->size(); j++)
|
||||
if (rect.contains(src->at(j).coordinates))
|
||||
@ -38,58 +38,6 @@ SubFile *VectorTile::file(SubFile::Type type)
|
||||
}
|
||||
}
|
||||
|
||||
SubFile *VectorTile::addFile(IMG *img, SubFile::Type type)
|
||||
{
|
||||
switch (type) {
|
||||
case SubFile::TRE:
|
||||
_tre = new TREFile(img);
|
||||
return _tre;
|
||||
case SubFile::RGN:
|
||||
_rgn = new RGNFile(img);
|
||||
return _rgn;
|
||||
case SubFile::LBL:
|
||||
_lbl = new LBLFile(img);
|
||||
return _lbl;
|
||||
case SubFile::NET:
|
||||
_net = new NETFile(img);
|
||||
return _net;
|
||||
case SubFile::NOD:
|
||||
_nod = new NODFile(img);
|
||||
return _nod;
|
||||
case SubFile::GMP:
|
||||
_gmp = new SubFile(img);
|
||||
return _gmp;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
SubFile *VectorTile::addFile(const QString &path, SubFile::Type type)
|
||||
{
|
||||
switch (type) {
|
||||
case SubFile::TRE:
|
||||
_tre = new TREFile(path);
|
||||
return _tre;
|
||||
case SubFile::RGN:
|
||||
_rgn = new RGNFile(path);
|
||||
return _rgn;
|
||||
case SubFile::LBL:
|
||||
_lbl = new LBLFile(path);
|
||||
return _lbl;
|
||||
case SubFile::NET:
|
||||
_net = new NETFile(path);
|
||||
return _net;
|
||||
case SubFile::NOD:
|
||||
_nod = new NODFile(path);
|
||||
return _nod;
|
||||
case SubFile::GMP:
|
||||
_gmp = new SubFile(path);
|
||||
return _gmp;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool VectorTile::init()
|
||||
{
|
||||
if (_gmp && !initGMP())
|
||||
@ -120,23 +68,54 @@ bool VectorTile::initGMP()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VectorTile::load(SubFile::Handle &rgnHdl, SubFile::Handle &lblHdl,
|
||||
SubFile::Handle &netHdl, SubFile::Handle &nodHdl)
|
||||
{
|
||||
_loaded = -1;
|
||||
|
||||
if (!_rgn->load(rgnHdl))
|
||||
return false;
|
||||
if (_lbl && !_lbl->load(lblHdl, _rgn, rgnHdl))
|
||||
return false;
|
||||
if (_net && !_net->load(netHdl, _rgn, rgnHdl))
|
||||
return false;
|
||||
if (_nod && !_nod->load(nodHdl))
|
||||
return false;
|
||||
|
||||
_loaded = 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void VectorTile::clear()
|
||||
{
|
||||
_tre->clear();
|
||||
_rgn->clear();
|
||||
if (_lbl)
|
||||
_lbl->clear();
|
||||
if (_net)
|
||||
_net->clear();
|
||||
|
||||
_loaded = 0;
|
||||
}
|
||||
|
||||
void VectorTile::polys(const RectC &rect, int bits, bool baseMap,
|
||||
QList<IMG::Poly> *polygons, QList<IMG::Poly> *lines,
|
||||
QCache<const SubDiv *, IMG::Polys> *polyCache) const
|
||||
QList<MapData::Poly> *polygons, QList<MapData::Poly> *lines,
|
||||
QCache<const SubDiv *, MapData::Polys> *polyCache)
|
||||
{
|
||||
SubFile::Handle rgnHdl(_rgn), lblHdl(_lbl), netHdl(_net), nodHdl(_nod);
|
||||
|
||||
if (!_rgn->initialized() && !_rgn->init(rgnHdl))
|
||||
if (_loaded < 0 || (!_loaded && !load(rgnHdl, lblHdl, netHdl, nodHdl)))
|
||||
return;
|
||||
|
||||
QList<SubDiv*> subdivs = _tre->subdivs(rect, bits, baseMap);
|
||||
for (int i = 0; i < subdivs.size(); i++) {
|
||||
SubDiv *subdiv = subdivs.at(i);
|
||||
|
||||
IMG::Polys *polys = polyCache->object(subdiv);
|
||||
MapData::Polys *polys = polyCache->object(subdiv);
|
||||
if (!polys) {
|
||||
quint32 shift = _tre->shift(subdiv->bits());
|
||||
QList<IMG::Poly> p, l;
|
||||
QList<MapData::Poly> p, l;
|
||||
|
||||
if (!subdiv->initialized() && !_rgn->subdivInit(rgnHdl, subdiv))
|
||||
continue;
|
||||
@ -154,7 +133,7 @@ void VectorTile::polys(const RectC &rect, int bits, bool baseMap,
|
||||
|
||||
copyPolys(rect, &p, polygons);
|
||||
copyPolys(rect, &l, lines);
|
||||
polyCache->insert(subdiv, new IMG::Polys(p, l));
|
||||
polyCache->insert(subdiv, new MapData::Polys(p, l));
|
||||
} else {
|
||||
copyPolys(rect, &(polys->polygons), polygons);
|
||||
copyPolys(rect, &(polys->lines), lines);
|
||||
@ -163,21 +142,21 @@ void VectorTile::polys(const RectC &rect, int bits, bool baseMap,
|
||||
}
|
||||
|
||||
void VectorTile::points(const RectC &rect, int bits, bool baseMap,
|
||||
QList<IMG::Point> *points, QCache<const SubDiv *,
|
||||
QList<IMG::Point> > *pointCache) const
|
||||
QList<MapData::Point> *points, QCache<const SubDiv *,
|
||||
QList<MapData::Point> > *pointCache)
|
||||
{
|
||||
SubFile::Handle rgnHdl(_rgn), lblHdl(_lbl);
|
||||
SubFile::Handle rgnHdl(_rgn), lblHdl(_lbl), netHdl(_net), nodHdl(_nod);
|
||||
|
||||
if (!_rgn->initialized() && !_rgn->init(rgnHdl))
|
||||
if (_loaded < 0 || (!_loaded && !load(rgnHdl, lblHdl, netHdl, nodHdl)))
|
||||
return;
|
||||
|
||||
QList<SubDiv*> subdivs = _tre->subdivs(rect, bits, baseMap);
|
||||
for (int i = 0; i < subdivs.size(); i++) {
|
||||
SubDiv *subdiv = subdivs.at(i);
|
||||
|
||||
QList<IMG::Point> *pl = pointCache->object(subdiv);
|
||||
QList<MapData::Point> *pl = pointCache->object(subdiv);
|
||||
if (!pl) {
|
||||
QList<IMG::Point> p;
|
||||
QList<MapData::Point> p;
|
||||
|
||||
if (!subdiv->initialized() && !_rgn->subdivInit(rgnHdl, subdiv))
|
||||
continue;
|
||||
@ -189,7 +168,7 @@ void VectorTile::points(const RectC &rect, int bits, bool baseMap,
|
||||
_rgn->extPointObjects(rgnHdl, subdiv, _lbl, lblHdl, &p);
|
||||
|
||||
copyPoints(rect, &p, points);
|
||||
pointCache->insert(subdiv, new QList<IMG::Point>(p));
|
||||
pointCache->insert(subdiv, new QList<MapData::Point>(p));
|
||||
} else
|
||||
copyPoints(rect, pl, points);
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
#ifndef VECTORTILE_H
|
||||
#define VECTORTILE_H
|
||||
|
||||
#include "trefile.h"
|
||||
#include "trefile.h"
|
||||
#include "rgnfile.h"
|
||||
#include "lblfile.h"
|
||||
@ -10,7 +9,8 @@
|
||||
|
||||
class VectorTile {
|
||||
public:
|
||||
VectorTile() : _tre(0), _rgn(0), _lbl(0), _net(0), _nod(0), _gmp(0) {}
|
||||
VectorTile()
|
||||
: _tre(0), _rgn(0), _lbl(0), _net(0), _nod(0), _gmp(0), _loaded(0) {}
|
||||
~VectorTile()
|
||||
{
|
||||
delete _tre; delete _rgn; delete _lbl; delete _net; delete _nod;
|
||||
@ -19,21 +19,19 @@ public:
|
||||
|
||||
bool init();
|
||||
void markAsBasemap() {_tre->markAsBasemap();}
|
||||
void clear() {_tre->clear();}
|
||||
void clear();
|
||||
|
||||
const RectC &bounds() const {return _tre->bounds();}
|
||||
Range zooms() const {return _tre->zooms();}
|
||||
|
||||
SubFile *file(SubFile::Type type);
|
||||
SubFile *addFile(IMG *img, SubFile::Type type);
|
||||
SubFile *addFile(const QString &path, SubFile::Type type);
|
||||
|
||||
void polys(const RectC &rect, int bits, bool baseMap,
|
||||
QList<IMG::Poly> *polygons, QList<IMG::Poly> *lines,
|
||||
QCache<const SubDiv *, IMG::Polys> *polyCache) const;
|
||||
QList<MapData::Poly> *polygons, QList<MapData::Poly> *lines,
|
||||
QCache<const SubDiv *, MapData::Polys> *polyCache);
|
||||
void points(const RectC &rect, int bits, bool baseMap,
|
||||
QList<IMG::Point> *points, QCache<const SubDiv*,
|
||||
QList<IMG::Point> > *pointCache) const;
|
||||
QList<MapData::Point> *points, QCache<const SubDiv*,
|
||||
QList<MapData::Point> > *pointCache);
|
||||
|
||||
static bool isTileFile(SubFile::Type type)
|
||||
{
|
||||
@ -42,8 +40,37 @@ public:
|
||||
|| type == SubFile::NOD || type == SubFile::GMP);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
SubFile *addFile(T *container, SubFile::Type type)
|
||||
{
|
||||
switch (type) {
|
||||
case SubFile::TRE:
|
||||
_tre = new TREFile(container);
|
||||
return _tre;
|
||||
case SubFile::RGN:
|
||||
_rgn = new RGNFile(container);
|
||||
return _rgn;
|
||||
case SubFile::LBL:
|
||||
_lbl = new LBLFile(container);
|
||||
return _lbl;
|
||||
case SubFile::NET:
|
||||
_net = new NETFile(container);
|
||||
return _net;
|
||||
case SubFile::NOD:
|
||||
_nod = new NODFile(container);
|
||||
return _nod;
|
||||
case SubFile::GMP:
|
||||
_gmp = new SubFile(container);
|
||||
return _gmp;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool initGMP();
|
||||
bool load(SubFile::Handle &rgnHdl, SubFile::Handle &lblHdl,
|
||||
SubFile::Handle &netHdl, SubFile::Handle &nodHdl);
|
||||
|
||||
TREFile *_tre;
|
||||
RGNFile *_rgn;
|
||||
@ -51,6 +78,8 @@ private:
|
||||
NETFile *_net;
|
||||
NODFile *_nod;
|
||||
SubFile *_gmp;
|
||||
|
||||
int _loaded;
|
||||
};
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
|
Loading…
Reference in New Issue
Block a user