mirror of
https://github.com/tumic0/GPXSee.git
synced 2024-11-30 22:51:16 +01:00
Do not cache the raster data
This commit is contained in:
parent
02c3682758
commit
33f2002a52
@ -12,7 +12,7 @@ public:
|
|||||||
GMAP(const QString &fileName);
|
GMAP(const QString &fileName);
|
||||||
~GMAP();
|
~GMAP();
|
||||||
|
|
||||||
QString fileName() const {return _fileName;}
|
const QString &fileName() const {return _fileName;}
|
||||||
|
|
||||||
static bool isGMAP(const QString &path);
|
static bool isGMAP(const QString &path);
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include <QMap>
|
#include <QMap>
|
||||||
#include <QtEndian>
|
#include <QtEndian>
|
||||||
|
#include <QFile>
|
||||||
#include "vectortile.h"
|
#include "vectortile.h"
|
||||||
#include "img.h"
|
#include "img.h"
|
||||||
|
|
||||||
@ -24,7 +25,7 @@ static SubFile::Type tileType(const char str[3])
|
|||||||
return SubFile::Unknown;
|
return SubFile::Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
IMG::IMG(const QString &fileName) : _file(fileName)
|
IMG::IMG(const QString &fileName) : _fileName(fileName)
|
||||||
{
|
{
|
||||||
#define CHECK(condition) \
|
#define CHECK(condition) \
|
||||||
if (!(condition)) { \
|
if (!(condition)) { \
|
||||||
@ -33,19 +34,20 @@ IMG::IMG(const QString &fileName) : _file(fileName)
|
|||||||
return; \
|
return; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QFile file(fileName);
|
||||||
TileMap tileMap;
|
TileMap tileMap;
|
||||||
QByteArray typFile;
|
QByteArray typFile;
|
||||||
|
|
||||||
if (!_file.open(QFile::ReadOnly)) {
|
if (!file.open(QFile::ReadOnly)) {
|
||||||
_errorString = _file.errorString();
|
_errorString = file.errorString();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read IMG header
|
// Read IMG header
|
||||||
char signature[7], identifier[7];
|
char signature[7], identifier[7];
|
||||||
_file.read((char*)&_key, 1) && _file.seek(0x10)
|
file.read((char*)&_key, 1) && file.seek(0x10)
|
||||||
&& read(signature, sizeof(signature)) && _file.seek(0x41)
|
&& read(file, signature, sizeof(signature)) && file.seek(0x41)
|
||||||
&& read(identifier, sizeof(identifier));
|
&& read(file, identifier, sizeof(identifier));
|
||||||
if (memcmp(signature, "DSKIMG", sizeof(signature))
|
if (memcmp(signature, "DSKIMG", sizeof(signature))
|
||||||
|| memcmp(identifier, "GARMIN", sizeof(identifier))) {
|
|| memcmp(identifier, "GARMIN", sizeof(identifier))) {
|
||||||
_errorString = "Not a Garmin IMG file";
|
_errorString = "Not a Garmin IMG file";
|
||||||
@ -53,9 +55,9 @@ IMG::IMG(const QString &fileName) : _file(fileName)
|
|||||||
}
|
}
|
||||||
char d1[20], d2[31];
|
char d1[20], d2[31];
|
||||||
quint8 e1, e2;
|
quint8 e1, e2;
|
||||||
CHECK(_file.seek(0x49) && read(d1, sizeof(d1)) && _file.seek(0x61)
|
CHECK(file.seek(0x49) && read(file, d1, sizeof(d1)) && file.seek(0x61)
|
||||||
&& readValue(e1) && readValue(e2) && _file.seek(0x65)
|
&& readValue(file, e1) && readValue(file, e2) && file.seek(0x65)
|
||||||
&& read(d2, sizeof(d2)));
|
&& read(file, d2, sizeof(d2)));
|
||||||
|
|
||||||
QByteArray nba(QByteArray(d1, sizeof(d1)) + QByteArray(d2, sizeof(d2)));
|
QByteArray nba(QByteArray(d1, sizeof(d1)) + QByteArray(d2, sizeof(d2)));
|
||||||
_name = QString::fromLatin1(nba.constData(), nba.size()-1).trimmed();
|
_name = QString::fromLatin1(nba.constData(), nba.size()-1).trimmed();
|
||||||
@ -66,7 +68,7 @@ IMG::IMG(const QString &fileName) : _file(fileName)
|
|||||||
quint64 offset = 0x200;
|
quint64 offset = 0x200;
|
||||||
// Skip unused FAT blocks if any
|
// Skip unused FAT blocks if any
|
||||||
while (true) {
|
while (true) {
|
||||||
CHECK(_file.seek(offset) && readValue(flag));
|
CHECK(file.seek(offset) && readValue(file, flag));
|
||||||
if (flag)
|
if (flag)
|
||||||
break;
|
break;
|
||||||
offset += 512;
|
offset += 512;
|
||||||
@ -76,15 +78,17 @@ IMG::IMG(const QString &fileName) : _file(fileName)
|
|||||||
char name[8], type[3];
|
char name[8], type[3];
|
||||||
quint32 size;
|
quint32 size;
|
||||||
quint16 part;
|
quint16 part;
|
||||||
CHECK(_file.seek(offset + 12) && readValue(size));
|
CHECK(file.seek(offset + 12) && readValue(file, size));
|
||||||
offset += 512;
|
offset += 512;
|
||||||
int cnt = (size - offset) / 512;
|
int cnt = (size - offset) / 512;
|
||||||
|
|
||||||
// Read FAT blocks describing the IMG sub-files
|
// Read FAT blocks describing the IMG sub-files
|
||||||
for (int i = 0; i < cnt; i++) {
|
for (int i = 0; i < cnt; i++) {
|
||||||
quint16 block;
|
quint16 block;
|
||||||
CHECK(_file.seek(offset) && readValue(flag) && read(name, sizeof(name))
|
CHECK(file.seek(offset) && readValue(file, flag)
|
||||||
&& read(type, sizeof(type)) && readValue(size) && readValue(part));
|
&& read(file, name, sizeof(name))
|
||||||
|
&& read(file, type, sizeof(type)) && readValue(file, size)
|
||||||
|
&& readValue(file, part));
|
||||||
SubFile::Type tt = tileType(type);
|
SubFile::Type tt = tileType(type);
|
||||||
|
|
||||||
QByteArray fn(name, sizeof(name));
|
QByteArray fn(name, sizeof(name));
|
||||||
@ -97,16 +101,16 @@ IMG::IMG(const QString &fileName) : _file(fileName)
|
|||||||
} else
|
} else
|
||||||
tile = *it;
|
tile = *it;
|
||||||
|
|
||||||
SubFile *file = part ? tile->file(tt)
|
SubFile *subFile = part ? tile->file(tt)
|
||||||
: tile->addFile(this, tt);
|
: tile->addFile(this, tt);
|
||||||
CHECK(file);
|
CHECK(subFile);
|
||||||
|
|
||||||
_file.seek(offset + 0x20);
|
file.seek(offset + 0x20);
|
||||||
for (int i = 0; i < 240; i++) {
|
for (int i = 0; i < 240; i++) {
|
||||||
CHECK(readValue(block));
|
CHECK(readValue(file, block));
|
||||||
if (block == 0xFFFF)
|
if (block == 0xFFFF)
|
||||||
break;
|
break;
|
||||||
file->addBlock(block);
|
subFile->addBlock(block);
|
||||||
}
|
}
|
||||||
} else if (tt == SubFile::TYP) {
|
} else if (tt == SubFile::TYP) {
|
||||||
SubFile *typ = 0;
|
SubFile *typ = 0;
|
||||||
@ -118,9 +122,9 @@ IMG::IMG(const QString &fileName) : _file(fileName)
|
|||||||
typ = _typ;
|
typ = _typ;
|
||||||
|
|
||||||
if (typ) {
|
if (typ) {
|
||||||
_file.seek(offset + 0x20);
|
file.seek(offset + 0x20);
|
||||||
for (int i = 0; i < 240; i++) {
|
for (int i = 0; i < 240; i++) {
|
||||||
CHECK(readValue(block));
|
CHECK(readValue(file, block));
|
||||||
if (block == 0xFFFF)
|
if (block == 0xFFFF)
|
||||||
break;
|
break;
|
||||||
typ->addBlock(block);
|
typ->addBlock(block);
|
||||||
@ -138,7 +142,7 @@ IMG::IMG(const QString &fileName) : _file(fileName)
|
|||||||
VectorTile *tile = it.value();
|
VectorTile *tile = it.value();
|
||||||
|
|
||||||
if (!tile->init()) {
|
if (!tile->init()) {
|
||||||
qWarning("%s: %s: Invalid map tile", qPrintable(_file.fileName()),
|
qWarning("%s: %s: Invalid map tile", qPrintable(file.fileName()),
|
||||||
qPrintable(it.key()));
|
qPrintable(it.key()));
|
||||||
delete tile;
|
delete tile;
|
||||||
continue;
|
continue;
|
||||||
@ -178,20 +182,20 @@ IMG::IMG(const QString &fileName) : _file(fileName)
|
|||||||
_valid = true;
|
_valid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
qint64 IMG::read(char *data, qint64 maxSize)
|
qint64 IMG::read(QFile &file, char *data, qint64 maxSize)
|
||||||
{
|
{
|
||||||
qint64 ret = _file.read(data, maxSize);
|
qint64 ret = file.read(data, maxSize);
|
||||||
if (_key)
|
if (_key)
|
||||||
for (int i = 0; i < ret; i++)
|
for (int i = 0; i < ret; i++)
|
||||||
data[i] ^= _key;
|
data[i] ^= _key;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T> bool IMG::readValue(T &val)
|
template<class T> bool IMG::readValue(QFile &file, T &val)
|
||||||
{
|
{
|
||||||
T data;
|
T data;
|
||||||
|
|
||||||
if (read((char*)&data, sizeof(T)) < (qint64)sizeof(T))
|
if (read(file, (char*)&data, sizeof(T)) < (qint64)sizeof(T))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
val = qFromLittleEndian(data);
|
val = qFromLittleEndian(data);
|
||||||
@ -199,11 +203,11 @@ template<class T> bool IMG::readValue(T &val)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IMG::readBlock(int blockNum, char *data)
|
bool IMG::readBlock(QFile &file, int blockNum, char *data)
|
||||||
{
|
{
|
||||||
if (!_file.seek((quint64)blockNum << _blockBits))
|
if (!file.seek((quint64)blockNum << _blockBits))
|
||||||
return false;
|
return false;
|
||||||
if (read(data, 1ULL<<_blockBits) < (qint64)(1ULL<<_blockBits))
|
if (read(file, data, 1ULL<<_blockBits) < (qint64)(1ULL<<_blockBits))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -1,25 +1,26 @@
|
|||||||
#ifndef IMG_H
|
#ifndef IMG_H
|
||||||
#define IMG_H
|
#define IMG_H
|
||||||
|
|
||||||
#include <QFile>
|
|
||||||
#include "mapdata.h"
|
#include "mapdata.h"
|
||||||
|
|
||||||
|
class QFile;
|
||||||
|
|
||||||
class IMG : public MapData
|
class IMG : public MapData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IMG(const QString &fileName);
|
IMG(const QString &fileName);
|
||||||
|
|
||||||
QString fileName() const {return _file.fileName();}
|
const QString &fileName() const {return _fileName;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class SubFile;
|
friend class SubFile;
|
||||||
|
|
||||||
unsigned blockBits() const {return _blockBits;}
|
unsigned blockBits() const {return _blockBits;}
|
||||||
bool readBlock(int blockNum, char *data);
|
bool readBlock(QFile &file, int blockNum, char *data);
|
||||||
qint64 read(char *data, qint64 maxSize);
|
qint64 read(QFile &file, char *data, qint64 maxSize);
|
||||||
template<class T> bool readValue(T &val);
|
template<class T> bool readValue(QFile &file, T &val);
|
||||||
|
|
||||||
QFile _file;
|
QString _fileName;
|
||||||
quint8 _key;
|
quint8 _key;
|
||||||
unsigned _blockBits;
|
unsigned _blockBits;
|
||||||
};
|
};
|
||||||
|
@ -94,20 +94,23 @@ bool LBLFile::load(Handle &hdl, const RGNFile *rgn, Handle &rgnHdl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (hdrLen >= 0x19A) {
|
if (hdrLen >= 0x19A) {
|
||||||
quint32 size, flags;
|
quint32 offset, recordSize, size, flags;
|
||||||
if (!(seek(hdl, _gmpOffset + 0x184) && readUInt32(hdl, _imgOffsetsOffset)
|
if (!(seek(hdl, _gmpOffset + 0x184) && readUInt32(hdl, offset)
|
||||||
&& readUInt32(hdl, size) && readUInt16(hdl, _imgOffsetsRecordSize)
|
&& readUInt32(hdl, size) && readUInt16(hdl, recordSize)
|
||||||
&& readUInt32(hdl, flags) && readUInt32(hdl, _imgOffset)
|
&& readUInt32(hdl, flags) && readUInt32(hdl, _imgOffset)
|
||||||
&& readUInt32(hdl, _imgSize)))
|
&& readUInt32(hdl, _imgSize)))
|
||||||
return false;
|
return false;
|
||||||
_imgOffsetsCount = size ? size / _imgOffsetsRecordSize : 0;
|
quint32 count = size ? size / recordSize : 0;
|
||||||
|
|
||||||
quint32 maxId = _imgOffsetsCount - 1;
|
quint32 maxId = count - 1;
|
||||||
_imgOffsetIdSize = 0;
|
_imgOffsetIdSize = 0;
|
||||||
do {
|
do {
|
||||||
_imgOffsetIdSize++;
|
_imgOffsetIdSize++;
|
||||||
maxId = maxId >> 8;
|
maxId = maxId >> 8;
|
||||||
} while (maxId != 0);
|
} while (maxId != 0);
|
||||||
|
|
||||||
|
if (!loadFiles(hdl, count, offset, recordSize))
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_encoding == 11) {
|
if (_encoding == 11) {
|
||||||
@ -301,31 +304,43 @@ Label LBLFile::label(Handle &hdl, quint32 offset, bool poi, bool capitalize) con
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray LBLFile::readImage(Handle &hdl, quint32 id) const
|
bool LBLFile::loadFiles(Handle &hdl, quint32 count, quint32 offset,
|
||||||
|
quint32 recordSize)
|
||||||
{
|
{
|
||||||
quint32 offset, nextOffset, size;
|
_rasters.resize(count);
|
||||||
|
|
||||||
if (id >= _imgOffsetsCount)
|
for (quint32 i = 0; i < count; i++) {
|
||||||
return QByteArray();
|
quint32 currentOffset, nextOffset, size;
|
||||||
|
|
||||||
if (!(seek(hdl, _imgOffsetsOffset + id * _imgOffsetsRecordSize)
|
if (!(seek(hdl, offset + i * recordSize)
|
||||||
&& readVUInt32(hdl, _imgOffsetsRecordSize, offset)))
|
&& readVUInt32(hdl, recordSize, currentOffset)))
|
||||||
return QByteArray();
|
return false;
|
||||||
if (id == _imgOffsetsCount - 1)
|
if (i == count - 1)
|
||||||
nextOffset = _imgSize;
|
nextOffset = _imgSize;
|
||||||
else {
|
else {
|
||||||
if (!readVUInt32(hdl, _imgOffsetsRecordSize, nextOffset))
|
if (!readVUInt32(hdl, recordSize, nextOffset))
|
||||||
return QByteArray();
|
return false;
|
||||||
}
|
}
|
||||||
size = nextOffset - offset;
|
size = nextOffset - currentOffset;
|
||||||
|
|
||||||
if (!seek(hdl, _imgOffset + offset))
|
_rasters[i] = File(currentOffset, size);
|
||||||
return QByteArray();
|
}
|
||||||
QByteArray ba;
|
|
||||||
ba.resize(size);
|
|
||||||
for (quint32 i = 0; i < size; i++)
|
|
||||||
if (!readUInt8(hdl, *(ba.data() + i)))
|
|
||||||
return QByteArray();
|
|
||||||
|
|
||||||
return ba;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QImage LBLFile::readImage(Handle &hdl, quint32 id) const
|
||||||
|
{
|
||||||
|
if (id >= (quint32)_rasters.size())
|
||||||
|
return QImage();
|
||||||
|
|
||||||
|
if (!seek(hdl, _imgOffset + _rasters.at(id).offset))
|
||||||
|
return QImage();
|
||||||
|
QByteArray ba;
|
||||||
|
ba.resize(_rasters.at(id).size);
|
||||||
|
for (int i = 0; i < ba.size(); i++)
|
||||||
|
if (!readUInt8(hdl, *(ba.data() + i)))
|
||||||
|
return QImage();
|
||||||
|
|
||||||
|
return QImage::fromData(ba);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#ifndef LBLFILE_H
|
#ifndef LBLFILE_H
|
||||||
#define LBLFILE_H
|
#define LBLFILE_H
|
||||||
|
|
||||||
|
#include <QImage>
|
||||||
#include "common/textcodec.h"
|
#include "common/textcodec.h"
|
||||||
#include "subfile.h"
|
#include "subfile.h"
|
||||||
#include "label.h"
|
#include "label.h"
|
||||||
@ -13,16 +14,16 @@ class LBLFile : public SubFile
|
|||||||
public:
|
public:
|
||||||
LBLFile(IMG *img)
|
LBLFile(IMG *img)
|
||||||
: SubFile(img), _huffmanText(0), _table(0), _offset(0), _size(0),
|
: SubFile(img), _huffmanText(0), _table(0), _offset(0), _size(0),
|
||||||
_poiOffset(0), _poiSize(0), _imgOffsetsCount(0), _imgOffsetIdSize(0),
|
_poiOffset(0), _poiSize(0), _imgOffsetIdSize(0), _poiMultiplier(0),
|
||||||
_poiMultiplier(0), _multiplier(0), _encoding(0) {}
|
_multiplier(0), _encoding(0) {}
|
||||||
LBLFile(const QString *path)
|
LBLFile(const QString *path)
|
||||||
: SubFile(path), _huffmanText(0), _table(0), _offset(0), _size(0),
|
: SubFile(path), _huffmanText(0), _table(0), _offset(0), _size(0),
|
||||||
_poiOffset(0), _poiSize(0), _imgOffsetsCount(0), _imgOffsetIdSize(0),
|
_poiOffset(0), _poiSize(0), _imgOffsetIdSize(0), _poiMultiplier(0),
|
||||||
_poiMultiplier(0), _multiplier(0), _encoding(0) {}
|
_multiplier(0), _encoding(0) {}
|
||||||
LBLFile(SubFile *gmp, quint32 offset) : SubFile(gmp, offset),
|
LBLFile(SubFile *gmp, quint32 offset) : SubFile(gmp, offset),
|
||||||
_huffmanText(0), _table(0), _offset(0), _size(0), _poiOffset(0),
|
_huffmanText(0), _table(0), _offset(0), _size(0), _poiOffset(0),
|
||||||
_poiSize(0), _imgOffsetsCount(0), _imgOffsetIdSize(0), _poiMultiplier(0),
|
_poiSize(0), _imgOffsetIdSize(0), _poiMultiplier(0), _multiplier(0),
|
||||||
_multiplier(0), _encoding(0) {}
|
_encoding(0) {}
|
||||||
~LBLFile();
|
~LBLFile();
|
||||||
|
|
||||||
bool load(Handle &hdl, const RGNFile *rgn, Handle &rgnHdl);
|
bool load(Handle &hdl, const RGNFile *rgn, Handle &rgnHdl);
|
||||||
@ -32,13 +33,23 @@ public:
|
|||||||
bool capitalize = true) const;
|
bool capitalize = true) const;
|
||||||
|
|
||||||
quint8 imageIdSize() const {return _imgOffsetIdSize;}
|
quint8 imageIdSize() const {return _imgOffsetIdSize;}
|
||||||
QByteArray readImage(Handle &hdl, quint32 id) const;
|
QImage readImage(Handle &hdl, quint32 id) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct File {
|
||||||
|
File() : offset(0), size(0) {}
|
||||||
|
File(quint32 offset, quint32 size) : offset(offset), size(size) {}
|
||||||
|
|
||||||
|
quint32 offset;
|
||||||
|
quint32 size;
|
||||||
|
};
|
||||||
|
|
||||||
Label str2label(const QVector<quint8> &str, bool capitalize) const;
|
Label str2label(const QVector<quint8> &str, bool capitalize) const;
|
||||||
Label label6b(Handle &hdl, quint32 offset, bool capitalize) const;
|
Label label6b(Handle &hdl, quint32 offset, bool capitalize) const;
|
||||||
Label label8b(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;
|
Label labelHuffman(Handle &hdl, quint32 offset, bool capitalize) const;
|
||||||
|
bool loadFiles(Handle &hdl, quint32 count, quint32 offset,
|
||||||
|
quint32 recordSize);
|
||||||
|
|
||||||
HuffmanText *_huffmanText;
|
HuffmanText *_huffmanText;
|
||||||
quint32 *_table;
|
quint32 *_table;
|
||||||
@ -47,15 +58,14 @@ private:
|
|||||||
quint32 _size;
|
quint32 _size;
|
||||||
quint32 _poiOffset;
|
quint32 _poiOffset;
|
||||||
quint32 _poiSize;
|
quint32 _poiSize;
|
||||||
quint32 _imgOffsetsOffset;
|
|
||||||
quint32 _imgOffsetsCount;
|
|
||||||
quint32 _imgOffsetsRecordSize;
|
|
||||||
quint32 _imgOffset;
|
quint32 _imgOffset;
|
||||||
quint32 _imgSize;
|
quint32 _imgSize;
|
||||||
quint8 _imgOffsetIdSize;
|
quint8 _imgOffsetIdSize;
|
||||||
quint8 _poiMultiplier;
|
quint8 _poiMultiplier;
|
||||||
quint8 _multiplier;
|
quint8 _multiplier;
|
||||||
quint8 _encoding;
|
quint8 _encoding;
|
||||||
|
|
||||||
|
QVector<File> _rasters;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // LBLFILE_H
|
#endif // LBLFILE_H
|
||||||
|
@ -60,7 +60,7 @@ public:
|
|||||||
void load();
|
void load();
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
virtual QString fileName() const = 0;
|
virtual const QString &fileName() const = 0;
|
||||||
|
|
||||||
bool isValid() const {return _valid;}
|
bool isValid() const {return _valid;}
|
||||||
QString errorString() const {return _errorString;}
|
QString errorString() const {return _errorString;}
|
||||||
|
@ -2,34 +2,37 @@
|
|||||||
#define RASTER_H
|
#define RASTER_H
|
||||||
|
|
||||||
#include <QRect>
|
#include <QRect>
|
||||||
#include <QByteArray>
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include "common/rectc.h"
|
#include "common/rectc.h"
|
||||||
#include "common/garmin.h"
|
#include "common/garmin.h"
|
||||||
|
|
||||||
|
class LBLFile;
|
||||||
|
|
||||||
class Raster {
|
class Raster {
|
||||||
public:
|
public:
|
||||||
Raster() {}
|
Raster() : _lbl(0) {}
|
||||||
Raster(const QByteArray &img, const QRect &rect) : _img(img), _rect(rect) {}
|
Raster(const LBLFile *lbl, quint32 id, const QRect &rect)
|
||||||
|
: _lbl(lbl), _id(id), _rect(rect) {}
|
||||||
|
|
||||||
const QByteArray &img() const {return _img;}
|
const LBLFile *lbl() const {return _lbl;}
|
||||||
|
quint32 id() const {return _id;}
|
||||||
const RectC rect() const
|
const RectC rect() const
|
||||||
{
|
{
|
||||||
return RectC(Coordinates(toWGS32(_rect.left()), toWGS32(_rect.top())),
|
return RectC(Coordinates(toWGS32(_rect.left()), toWGS32(_rect.top())),
|
||||||
Coordinates(toWGS32(_rect.right()), toWGS32(_rect.bottom())));
|
Coordinates(toWGS32(_rect.right()), toWGS32(_rect.bottom())));
|
||||||
}
|
}
|
||||||
bool isValid() const {return !_img.isNull();}
|
bool isValid() const {return (_lbl != 0);}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QByteArray _img;
|
const LBLFile *_lbl;
|
||||||
|
quint32 _id;
|
||||||
QRect _rect;
|
QRect _rect;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef QT_NO_DEBUG
|
#ifndef QT_NO_DEBUG
|
||||||
inline QDebug operator<<(QDebug dbg, const Raster &raster)
|
inline QDebug operator<<(QDebug dbg, const Raster &raster)
|
||||||
{
|
{
|
||||||
dbg.nospace() << "Raster(" << raster.img().size() << ", " << raster.rect()
|
dbg.nospace() << "Raster(" << raster.rect() << ")";
|
||||||
<< ")";
|
|
||||||
return dbg.space();
|
return dbg.space();
|
||||||
}
|
}
|
||||||
#endif // QT_NO_DEBUG
|
#endif // QT_NO_DEBUG
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "textpointitem.h"
|
#include "textpointitem.h"
|
||||||
#include "bitmapline.h"
|
#include "bitmapline.h"
|
||||||
#include "style.h"
|
#include "style.h"
|
||||||
|
#include "lblfile.h"
|
||||||
#include "rastertile.h"
|
#include "rastertile.h"
|
||||||
|
|
||||||
|
|
||||||
@ -224,8 +225,11 @@ void RasterTile::drawPolygons(QPainter *painter)
|
|||||||
QPointF br(_map->ll2xy(r.bottomRight()));
|
QPointF br(_map->ll2xy(r.bottomRight()));
|
||||||
QSize size(QRectF(tl, br).toRect().size());
|
QSize size(QRectF(tl, br).toRect().size());
|
||||||
|
|
||||||
painter->drawImage(tl, QImage::fromData(poly.raster.img()).
|
SubFile::Handle hdl(poly.raster.lbl());
|
||||||
scaled(size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
QImage img(poly.raster.lbl()->readImage(hdl, poly.raster.id()));
|
||||||
|
|
||||||
|
painter->drawImage(tl, img.scaled(size, Qt::IgnoreAspectRatio,
|
||||||
|
Qt::SmoothTransformation));
|
||||||
|
|
||||||
//painter->setPen(Qt::blue);
|
//painter->setPen(Qt::blue);
|
||||||
//painter->setBrush(Qt::NoBrush);
|
//painter->setBrush(Qt::NoBrush);
|
||||||
|
@ -30,7 +30,7 @@ RGNFile::~RGNFile()
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool RGNFile::readClassFields(Handle &hdl, SegmentType segmentType,
|
bool RGNFile::readClassFields(Handle &hdl, SegmentType segmentType,
|
||||||
MapData::Poly *poly, const LBLFile *lbl, Handle *lblHdl) const
|
MapData::Poly *poly, const LBLFile *lbl) const
|
||||||
{
|
{
|
||||||
quint8 flags;
|
quint8 flags;
|
||||||
quint32 rs;
|
quint32 rs;
|
||||||
@ -67,8 +67,8 @@ bool RGNFile::readClassFields(Handle &hdl, SegmentType segmentType,
|
|||||||
&& readUInt32(hdl, bottom) && readUInt32(hdl, left)))
|
&& readUInt32(hdl, bottom) && readUInt32(hdl, left)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
poly->raster = Raster(lbl->readImage(*lblHdl, id),
|
poly->raster = Raster(lbl, id, QRect(QPoint(left, top), QPoint(right,
|
||||||
QRect(QPoint(left, top), QPoint(right, bottom)));
|
bottom)));
|
||||||
|
|
||||||
rs -= lbl->imageIdSize() + 16;
|
rs -= lbl->imageIdSize() + 16;
|
||||||
}
|
}
|
||||||
@ -336,8 +336,7 @@ bool RGNFile::extPolyObjects(Handle &hdl, const SubDiv *subdiv, quint32 shift,
|
|||||||
|
|
||||||
if (subtype & 0x20 && !readUInt24(hdl, labelPtr))
|
if (subtype & 0x20 && !readUInt24(hdl, labelPtr))
|
||||||
return false;
|
return false;
|
||||||
if (subtype & 0x80 && !readClassFields(hdl, segmentType, &poly, lbl,
|
if (subtype & 0x80 && !readClassFields(hdl, segmentType, &poly, lbl))
|
||||||
&lblHdl))
|
|
||||||
return false;
|
return false;
|
||||||
if (subtype & 0x40 && !skipLclFields(hdl, segmentType == Line
|
if (subtype & 0x40 && !skipLclFields(hdl, segmentType == Line
|
||||||
? _linesLclFlags : _polygonsLclFlags))
|
? _linesLclFlags : _polygonsLclFlags))
|
||||||
|
@ -61,7 +61,7 @@ private:
|
|||||||
QMap<SegmentType, SubDiv::Segment> segments(Handle &hdl, SubDiv *subdiv)
|
QMap<SegmentType, SubDiv::Segment> segments(Handle &hdl, SubDiv *subdiv)
|
||||||
const;
|
const;
|
||||||
bool readClassFields(Handle &hdl, SegmentType segmentType,
|
bool readClassFields(Handle &hdl, SegmentType segmentType,
|
||||||
MapData::Poly *poly = 0, const LBLFile *lbl = 0, Handle *lblHdl = 0) const;
|
MapData::Poly *poly = 0, const LBLFile *lbl = 0) const;
|
||||||
bool skipLclFields(Handle &hdl, const quint32 flags[3]) const;
|
bool skipLclFields(Handle &hdl, const quint32 flags[3]) const;
|
||||||
bool skipGblFields(Handle &hdl, quint32 flags) const;
|
bool skipGblFields(Handle &hdl, quint32 flags) const;
|
||||||
|
|
||||||
|
@ -7,38 +7,37 @@
|
|||||||
|
|
||||||
bool SubFile::seek(Handle &handle, quint32 pos) const
|
bool SubFile::seek(Handle &handle, quint32 pos) const
|
||||||
{
|
{
|
||||||
if (handle._file) {
|
if (_img) {
|
||||||
int blockNum = pos >> BLOCK_BITS;
|
|
||||||
|
|
||||||
if (handle._blockNum != blockNum) {
|
|
||||||
if (!handle._file->seek((quint64)blockNum << BLOCK_BITS))
|
|
||||||
return false;
|
|
||||||
if (handle._file->read(handle._data.data(), (1<<BLOCK_BITS)) < 0)
|
|
||||||
return false;
|
|
||||||
handle._blockNum = blockNum;
|
|
||||||
}
|
|
||||||
|
|
||||||
handle._blockPos = mod2n(pos, 1U<<BLOCK_BITS);
|
|
||||||
handle._pos = pos;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
quint32 blockBits = _img->blockBits();
|
quint32 blockBits = _img->blockBits();
|
||||||
int blockNum = pos >> blockBits;
|
int blockNum = pos >> blockBits;
|
||||||
|
|
||||||
if (handle._blockNum != blockNum) {
|
if (handle._blockNum != blockNum) {
|
||||||
if (blockNum >= _blocks->size())
|
if (blockNum >= _blocks->size())
|
||||||
return false;
|
return false;
|
||||||
if (!_img->readBlock(_blocks->at(blockNum), handle._data.data()))
|
if (!_img->readBlock(handle._file, _blocks->at(blockNum),
|
||||||
|
handle._data.data()))
|
||||||
return false;
|
return false;
|
||||||
handle._blockNum = blockNum;
|
handle._blockNum = blockNum;
|
||||||
}
|
}
|
||||||
|
|
||||||
handle._blockPos = mod2n(pos, 1U<<blockBits);
|
handle._blockPos = mod2n(pos, 1U<<blockBits);
|
||||||
handle._pos = pos;
|
handle._pos = pos;
|
||||||
|
} else {
|
||||||
|
int blockNum = pos >> BLOCK_BITS;
|
||||||
|
|
||||||
|
if (handle._blockNum != blockNum) {
|
||||||
|
if (!handle._file.seek((quint64)blockNum << BLOCK_BITS))
|
||||||
|
return false;
|
||||||
|
if (handle._file.read(handle._data.data(), (1<<BLOCK_BITS)) < 0)
|
||||||
|
return false;
|
||||||
|
handle._blockNum = blockNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
handle._blockPos = mod2n(pos, 1U<<BLOCK_BITS);
|
||||||
|
handle._pos = pos;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SubFile::readVUInt32(Handle &hdl, quint32 &val) const
|
bool SubFile::readVUInt32(Handle &hdl, quint32 &val) const
|
||||||
|
@ -17,21 +17,26 @@ public:
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Handle(const SubFile *subFile)
|
Handle(const SubFile *subFile)
|
||||||
: _file(0), _blockNum(-1), _blockPos(-1), _pos(-1)
|
: _blockNum(-1), _blockPos(-1), _pos(-1)
|
||||||
{
|
{
|
||||||
if (subFile && subFile->_path) {
|
if (!subFile)
|
||||||
_file = new QFile(*(subFile->_path));
|
return;
|
||||||
_file->open(QIODevice::ReadOnly);
|
|
||||||
|
if (subFile->_path) {
|
||||||
|
_file.setFileName(*(subFile->_path));
|
||||||
_data.resize(1U<<BLOCK_BITS);
|
_data.resize(1U<<BLOCK_BITS);
|
||||||
} else if (subFile)
|
} else {
|
||||||
|
_file.setFileName(subFile->_img->fileName());
|
||||||
_data.resize(1U<<subFile->_img->blockBits());
|
_data.resize(1U<<subFile->_img->blockBits());
|
||||||
}
|
}
|
||||||
~Handle() {delete _file;}
|
|
||||||
|
_file.open(QIODevice::ReadOnly);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class SubFile;
|
friend class SubFile;
|
||||||
|
|
||||||
QFile *_file;
|
QFile _file;
|
||||||
QByteArray _data;
|
QByteArray _data;
|
||||||
int _blockNum;
|
int _blockNum;
|
||||||
int _blockPos;
|
int _blockPos;
|
||||||
|
Loading…
Reference in New Issue
Block a user