1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2025-07-05 07:02:51 +02:00

Compare commits

...

32 Commits
7.13 ... 7.14

Author SHA1 Message Date
d3558198ca Translated using Weblate (German)
Currently translated at 100.0% (343 of 343 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/de/
2019-09-29 11:58:18 +02:00
acc69f5c3d Merge branch 'origin/master' into Weblate. 2019-09-29 11:47:55 +02:00
7a900f2252 Version++ 2019-09-29 11:48:08 +02:00
dad76a4e89 Merge branch 'origin/master' into Weblate. 2019-09-29 11:24:33 +02:00
e28e69b248 Added support for enchanced altitude and speed entries 2019-09-29 11:24:20 +02:00
7fffd6a161 Merge branch 'origin/master' into Weblate. 2019-09-29 00:03:21 +02:00
c4fd82e5a0 Properly handle routes without elevation data as well 2019-09-29 00:03:14 +02:00
fa08c0dbea Properly handle files without elevation data 2019-09-28 23:56:59 +02:00
070eff2115 Print a warning message on unsupported IMG compression 2019-09-28 23:55:26 +02:00
20a4870904 Merge branch 'origin/master' into Weblate. 2019-09-21 00:37:02 +02:00
1bb9908936 Some more code cleanup 2019-09-21 00:36:49 +02:00
36555b3140 Code cleanup 2019-09-20 00:23:47 +02:00
6564fb36ab Merge branch 'origin/master' into Weblate. 2019-09-20 00:23:46 +02:00
1a3356b8fe Cosmetics 2019-09-18 09:18:09 +02:00
7ad64922c9 Merge branch 'origin/master' into Weblate. 2019-09-18 09:18:09 +02:00
64a8ec1b84 Merge branch 'origin/master' into Weblate. 2019-09-18 09:12:36 +02:00
0a75298b2b Made the variable record info parsing universal 2019-09-18 09:11:46 +02:00
99be5699af Merge branch 'origin/master' into Weblate. 2019-09-18 08:38:05 +02:00
cdb641b204 Properly read variable length values
Code cleanup
2019-09-18 08:37:33 +02:00
f57bd48840 Merge branch 'origin/master' into Weblate. 2019-09-10 19:45:52 +02:00
c2abf2c146 Prefer loading speed over "NT maps not supported" reporting 2019-09-10 19:45:06 +02:00
a5a2070ccc Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (343 of 343 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/pt_BR/
2019-09-09 12:35:04 +02:00
ed7cb1beb1 Translated using Weblate (Norwegian Bokmål)
Currently translated at 91.3% (313 of 343 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/nb_NO/
2019-09-09 12:35:04 +02:00
37d832bc7f Translated using Weblate (French)
Currently translated at 100.0% (343 of 343 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/fr/
2019-09-09 12:35:04 +02:00
c322bf9f68 Translated using Weblate (Turkish)
Currently translated at 100.0% (343 of 343 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/tr/
2019-09-07 21:35:43 +02:00
2705ffbbfe Translated using Weblate (Russian)
Currently translated at 100.0% (343 of 343 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/ru/
2019-09-07 00:22:41 +02:00
e8962dd50f Translated using Weblate (Czech)
Currently translated at 100.0% (343 of 343 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/cs/
2019-09-07 00:22:40 +02:00
b37e32d622 Translated using Weblate (Finnish)
Currently translated at 100.0% (343 of 343 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/fi/
2019-09-07 00:22:40 +02:00
2b1d0d2189 Translated using Weblate (Swedish)
Currently translated at 100.0% (343 of 343 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/sv/
2019-09-07 00:22:39 +02:00
33e3471ca3 Added pt_PT translation file stub 2019-09-06 20:10:40 +02:00
bf55f1e07d ts files update 2019-09-06 20:10:09 +02:00
37a0eec48f Added support for pseudo-NT IMG maps (e.g. TopoHispania) 2019-09-05 22:31:13 +02:00
36 changed files with 6413 additions and 2962 deletions

View File

@ -1,4 +1,4 @@
version: 7.13.{build}
version: 7.14.{build}
configuration: Release
platform: Any CPU
environment:

View File

@ -3,7 +3,7 @@ unix:!macx {
} else {
TARGET = GPXSee
}
VERSION = 7.13
VERSION = 7.14
QT += core \
gui \

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1860
lang/gpxsee_pt_PT.ts Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@
; The name of the installer
Name "GPXSee"
; Program version
!define VERSION "7.13"
!define VERSION "7.14"
; The file to write
OutFile "GPXSee-${VERSION}.exe"

View File

@ -7,7 +7,7 @@
; The name of the installer
Name "GPXSee"
; Program version
!define VERSION "7.13"
!define VERSION "7.14"
; The file to write
OutFile "GPXSee-${VERSION}_x64.exe"

View File

@ -265,6 +265,14 @@ bool FITParser::parseData(CTX &ctx, const MessageDefinition *def)
if (val != 0x7f)
ctx.trackpoint.setTemperature((qint8)val);
break;
case 73:
if (val != 0xffffffff)
ctx.trackpoint.setSpeed(val / 1000.0f);
break;
case 78:
if (val != 0xffffffff)
ctx.trackpoint.setElevation((val / 5.0) - 500);
break;
default:
break;

View File

@ -54,6 +54,7 @@ public:
return false;
return true;
}
bool hasTime() const
{
for (int i = 0; i < size(); i++) {

View File

@ -1,4 +1,3 @@
#include "dem.h"
#include "route.h"
@ -33,7 +32,8 @@ Graph Route::elevation() const
GraphSegment &gs = graph.last();
for (int i = 0; i < _data.size(); i++)
gs.append(GraphPoint(_distance.at(i), NAN, _data.at(i).elevation()));
if (_data.at(i).hasElevation())
gs.append(GraphPoint(_distance.at(i), NAN, _data.at(i).elevation()));
return graph;
}

View File

@ -1,4 +1,3 @@
#include "dem.h"
#include "track.h"
@ -177,7 +176,7 @@ Graph Track::elevation() const
GraphSegment gs;
for (int j = 0; j < sd.size(); j++) {
if (seg.outliers.contains(j))
if (!sd.at(j).hasElevation() || seg.outliers.contains(j))
continue;
gs.append(GraphPoint(seg.distance.at(j), seg.time.at(j),
sd.at(j).elevation()));

View File

@ -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());

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -1,10 +1,26 @@
#include "trefile.h"
#include "common/rectc.h"
#include "units.h"
#include "lblfile.h"
#include "netfile.h"
#include "rgnfile.h"
static int bitSize(quint8 baseSize, bool variableSign, bool extraBit)
{
int bits = 2;
if (baseSize <= 9)
bits += baseSize;
else
bits += 2 * baseSize - 9;
if (variableSign)
bits++;
if (extraBit)
bits++;
return bits;
}
bool RGNFile::BitStream::read(int bits, quint32 &val)
{
val = 0;
@ -34,29 +50,42 @@ bool RGNFile::BitStream::read(int bits, quint32 &val)
return true;
}
bool RGNFile::BitStream::readDelta(int bits, int sign, bool extraBit,
RGNFile::DeltaStream::DeltaStream(const SubFile &file, Handle &hdl,
quint32 length, quint8 info, bool extraBit, bool extended)
: BitStream(file, hdl, length), _readBits(0xFFFFFFFF)
{
_extraBit = extraBit ? 1 : 0;
if (!(sign(_lonSign) && sign(_latSign)))
return;
if (extended) {
quint32 b;
if (!read(1, b))
return;
}
_lonBits = bitSize(info & 0x0F, !_lonSign, extraBit);
_latBits = bitSize(info >> 4, !_latSign, false);
_readBits = _lonBits + _latBits;
}
bool RGNFile::DeltaStream::readDelta(int bits, int sign, int extraBit,
qint32 &delta)
{
quint32 value;
int bo = 0;
if (!read(bits, value))
return false;
if (extraBit) {
value>>=1;
bo = 1;
}
value >>= extraBit;
if (!sign) {
qint32 signMask = 1 << (bits - bo - 1);
qint32 signMask = 1 << (bits - extraBit - 1);
if (value & signMask) {
qint32 comp = value ^ signMask;
if (comp)
delta = comp - signMask;
else {
qint32 other;
if (!readDelta(bits - bo, sign, false, other))
if (!readDelta(bits - extraBit, sign, false, other))
return false;
if (other < 0)
delta = 1 - signMask + other;
@ -73,42 +102,15 @@ bool RGNFile::BitStream::readDelta(int bits, int sign, bool extraBit,
return true;
}
bool RGNFile::BitStream::finish()
{
while (_length--)
if (!_file.readByte(_hdl, _data))
return false;
return true;
}
bool RGNFile::init()
{
Handle hdl;
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)))
return false;
if (_offset + _size > size())
return false;
return true;
}
bool RGNFile::sign(BitStream &bs, int &val)
bool RGNFile::DeltaStream::sign(int &val)
{
quint32 bit;
val = 0;
if (!bs.read(1, bit))
if (!read(1, bit))
return false;
if (bit) {
if (!bs.read(1, bit))
if (!read(1, bit))
return false;
val = bit ? -1 : 1;
}
@ -116,20 +118,41 @@ bool RGNFile::sign(BitStream &bs, int &val)
return true;
}
int RGNFile::bitSize(quint8 baseSize, bool variableSign, bool extraBit)
bool RGNFile::init()
{
int bits = 2;
if (baseSize <= 9)
bits += baseSize;
else
bits += 2 * baseSize - 9;
Handle hdl;
quint16 hdrLen;
if (variableSign)
bits++;
if (extraBit)
bits++;
if (!(seek(hdl, _gmpOffset) && readUInt16(hdl, hdrLen)
&& seek(hdl, _gmpOffset + 0x15) && readUInt32(hdl, _offset)
&& readUInt32(hdl, _size)))
return false;
return bits;
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;
// NT maps
if (dictSize || dictOffset) {
qWarning("NT compression not supported");
return false;
}
}
_init = true;
return true;
}
bool RGNFile::polyObjects(const RectC &rect, Handle &hdl, const SubDiv *subdiv,
@ -167,28 +190,17 @@ bool RGNFile::polyObjects(const RectC &rect, Handle &hdl, const SubDiv *subdiv,
poly.type = (segment.type() == Segment::Polygon)
? ((quint32)(type & 0x7F)) << 8 : ((quint32)(type & 0x3F)) << 8;
RectC br;
QPoint pos(subdiv->lon() + ((qint32)lon<<(24-subdiv->bits())),
subdiv->lat() + ((qint32)lat<<(24-subdiv->bits())));
Coordinates c(toWGS84(pos.x()), toWGS84(pos.y()));
br = br.united(c);
RectC br(c, c);
poly.points.append(QPointF(c.lon(), c.lat()));
BitStream bs(*this, hdl, len);
int lonSign, latSign;
if (!sign(bs, lonSign) || !sign(bs, latSign))
return false;
bool extraBit = labelPtr & 0x400000;
int lonBits = bitSize(bitstreamInfo & 0x0F, !lonSign, extraBit);
int latBits = bitSize(bitstreamInfo >> 4, !latSign, false);
while (bs.hasNext(lonBits + latBits)) {
qint32 lonDelta, latDelta;
if (!(bs.readDelta(lonBits, lonSign, extraBit, lonDelta)
&& bs.readDelta(latBits, latSign, false, latDelta)))
return false;
qint32 lonDelta, latDelta;
DeltaStream stream(*this, hdl, len, bitstreamInfo, labelPtr & 0x400000,
false);
while (stream.readNext(lonDelta, latDelta)) {
pos.rx() += lonDelta<<(24-subdiv->bits());
pos.ry() += latDelta<<(24-subdiv->bits());
@ -196,7 +208,7 @@ bool RGNFile::polyObjects(const RectC &rect, Handle &hdl, const SubDiv *subdiv,
poly.points.append(QPointF(c.lon(), c.lat()));
br = br.united(c);
}
if (!bs.finish())
if (!(stream.atEnd() && stream.flush()))
return false;
if (!rect.intersects(br))
@ -222,10 +234,9 @@ bool RGNFile::extPolyObjects(const RectC &rect, Handle &hdl,
const SubDiv *subdiv, const Segment &segment, LBLFile *lbl, Handle &lblHdl,
QList<IMG::Poly> *polys) const
{
quint32 labelPtr;
quint8 type, subtype, len8, len82, bitstreamInfo;
quint32 len, labelPtr = 0;
quint8 type, subtype, bitstreamInfo;
qint16 lon, lat;
quint16 len;
if (!seek(hdl, segment.start()))
@ -235,7 +246,8 @@ bool RGNFile::extPolyObjects(const RectC &rect, Handle &hdl,
IMG::Poly poly;
if (!(readByte(hdl, type) && readByte(hdl, subtype)
&& readInt16(hdl, lon) && readInt16(hdl, lat) && readByte(hdl, len8)))
&& readInt16(hdl, lon) && readInt16(hdl, lat)
&& readVUInt32(hdl, len) && readByte(hdl, bitstreamInfo)))
return false;
if (subtype & 0x80) {
@ -243,40 +255,17 @@ bool RGNFile::extPolyObjects(const RectC &rect, Handle &hdl,
return false;
}
if (len8 & 0x01)
len = (len8>>1) - 1;
else {
if (!readByte(hdl, len82))
return false;
len = ((len8 | ((quint16)len82<<8))>>2) - 1;
}
if (!readByte(hdl, bitstreamInfo))
return false;
poly.type = 0x10000 + (quint16(type) << 8) + (subtype & 0x1F);
RectC br;
QPoint pos(subdiv->lon() + ((qint32)lon<<(24-subdiv->bits())),
subdiv->lat() + ((qint32)lat<<(24-subdiv->bits())));
Coordinates c(toWGS84(pos.x()), toWGS84(pos.y()));
br = br.united(c);
RectC br(c, c);
poly.points.append(QPointF(c.lon(), c.lat()));
BitStream bs(*this, hdl, len);
int lonSign, latSign;
if (!sign(bs, lonSign) || !sign(bs, latSign))
return false;
quint32 extraBit;
bs.read(1, extraBit);
int lonBits = bitSize(bitstreamInfo & 0x0F, !lonSign, extraBit);
int latBits = bitSize(bitstreamInfo >> 4, !latSign, extraBit);
while (bs.hasNext(lonBits + latBits)) {
qint32 lonDelta, latDelta;
if (!(bs.readDelta(lonBits, lonSign, false, lonDelta)
&& bs.readDelta(latBits, latSign, false, latDelta)))
return false;
qint32 lonDelta, latDelta;
DeltaStream stream(*this, hdl, len - 1, bitstreamInfo, false, true);
while (stream.readNext(lonDelta, latDelta)) {
pos.rx() += lonDelta<<(24-subdiv->bits());
pos.ry() += latDelta<<(24-subdiv->bits());
@ -284,19 +273,21 @@ bool RGNFile::extPolyObjects(const RectC &rect, Handle &hdl,
poly.points.append(QPointF(c.lon(), c.lat()));
br = br.united(c);
}
if (!bs.finish())
if (!(stream.atEnd() && stream.flush()))
return false;
if (subtype & 0x20) {
if ((subtype & 0x20)) {
if (!readUInt24(hdl, labelPtr))
return false;
if (lbl && (labelPtr & 0x3FFFFF))
poly.label = lbl->label(lblHdl, labelPtr & 0x3FFFFF);
}
} else
labelPtr = 0;
if (!rect.intersects(br))
continue;
if (lbl && (labelPtr & 0x3FFFFF))
poly.label = lbl->label(lblHdl, labelPtr & 0x3FFFFF);
polys->append(poly);
}
@ -404,7 +395,7 @@ void RGNFile::objects(const RectC &rect, const SubDiv *subdiv, LBLFile *lbl,
{
Handle rgnHdl, lblHdl, netHdl;
if (!_size && !init())
if (!_init && !init())
return;
QVector<RGNFile::Segment> seg(segments(rgnHdl, subdiv));
@ -436,7 +427,7 @@ void RGNFile::extObjects(const RectC &rect, const SubDiv *subdiv, LBLFile *lbl,
{
Handle rgnHdl, lblHdl;
if (!_size && !init())
if (!_init && !init())
return;
if (polygons && subdiv->polygonsOffset() != subdiv->polygonsEnd()) {

View File

@ -11,10 +11,13 @@ 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), _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) {}
void objects(const RectC &rect, const SubDiv *subdiv, LBLFile *lbl,
NETFile *net, QList<IMG::Poly> *polygons, QList<IMG::Poly> *lines,
@ -53,27 +56,45 @@ private:
class BitStream {
public:
BitStream(const SubFile &file, Handle &hdl, quint16 length)
BitStream(const SubFile &file, Handle &hdl, quint32 length)
: _file(file), _hdl(hdl), _length(length), _remaining(0) {}
bool read(int bits, quint32 &val);
bool readDelta(int bits, int sign, bool extraBit, qint32 &delta);
bool hasNext(int bits) const
{return _length * 8 + _remaining >= (quint32)bits;}
bool finish();
bool flush() {return _file.seek(_hdl, _hdl.pos + _length);}
quint32 bitsAvailable() const {return _length * 8 + _remaining;}
private:
const SubFile &_file;
Handle &_hdl;
quint16 _length;
quint32 _remaining;
quint32 _length, _remaining;
quint8 _data;
};
static bool sign(BitStream &bs, int &val);
static int bitSize(quint8 baseSize, bool variableSign, bool extraBit);
class DeltaStream : public BitStream {
public:
DeltaStream(const SubFile &file, Handle &hdl, quint32 length,
quint8 info, bool extraBit, bool extended);
bool readNext(qint32 &lonDelta, qint32 &latDelta)
{
return hasNext()
? (readDelta(_lonBits, _lonSign, _extraBit, lonDelta)
&& readDelta(_latBits, _latSign, false, latDelta))
: false;
}
bool atEnd() const {return (_readBits != 0xFFFFFFFF && !hasNext());}
private:
bool hasNext() const {return bitsAvailable() >= _readBits;}
bool sign(int &val);
bool readDelta(int bits, int sign, int extraBit, qint32 &delta);
int _lonSign, _latSign, _extraBit;
quint32 _lonBits, _latBits, _readBits;
};
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,
@ -99,6 +120,8 @@ private:
quint32 _linesSize;
quint32 _pointsOffset;
quint32 _pointsSize;
bool _init;
};
#ifndef QT_NO_DEBUG

View File

@ -942,7 +942,7 @@ Style::Style(SubFile *typ)
defaultPolygonStyle();
defaultPointStyle();
if (typ && typ->isValid())
if (typ)
parseTYPFile(typ);
}

View File

@ -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,9 +66,35 @@ bool SubFile::readByte(Handle &handle, quint8 &val) const
}
}
quint32 SubFile::size() const
bool SubFile::readVUInt32(Handle &hdl, quint32 &val) const
{
return _file ? (quint32)_file->size() : _size;
quint8 bytes, shift, b;
if (!readByte(hdl, b))
return false;
if ((b & 1) == 0) {
if ((b & 2) == 0) {
bytes = ((b >> 2) & 1) ^ 3;
shift = 5;
} else {
shift = 6;
bytes = 1;
}
} else {
shift = 7;
bytes = 0;
}
val = b >> (8 - shift);
for (int i = 1; i <= bytes; i++) {
if (!readByte(hdl, b))
return false;
val |= (((quint32)b) << (i * 8)) >> (8 - shift);
}
return true;
}
QString SubFile::fileName() const
@ -88,15 +106,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

View File

@ -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,28 @@ public:
return true;
}
quint16 offset() const {return _blocks.first();}
bool readVUInt32(Handle &hdl, quint32 &val) const;
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

View File

@ -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);

View File

@ -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();

View File

@ -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))
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;
}

View File

@ -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