1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-11-27 21:24:47 +01:00

Read/display extended (class) point labels

This commit is contained in:
Martin Tůma 2022-02-06 02:42:37 +01:00
parent 21b258809d
commit 5d6970c7ee
6 changed files with 97 additions and 74 deletions

View File

@ -137,7 +137,50 @@ void LBLFile::clear()
_rasters = 0; _rasters = 0;
} }
Label LBLFile::label6b(Handle &hdl, quint32 offset, bool capitalize, Label LBLFile::str2label(const QVector<quint8> &str, bool capitalize,
bool convert) const
{
Shield::Type shieldType = Shield::None;
QByteArray label, shieldLabel;
QByteArray *bap = &label;
int split = -1;
for (int i = 0; i < str.size(); i++) {
const quint8 &c = str.at(i);
if (c == 0 || c == 0x1d || c == 0x07)
break;
if (c == 0x1c)
capitalize = false;
else if ((c >= 0x1e && c <= 0x1f)) {
if (bap == &shieldLabel)
bap = &label;
else {
if (!bap->isEmpty())
bap->append('\n');
if (c == 0x1f && split < 0)
split = bap->size();
}
} else if (c < 0x07) {
shieldType = static_cast<Shield::Type>(c);
bap = &shieldLabel;
} else if (bap == &shieldLabel && c == 0x20) {
bap = &label;
} else
bap->append(c);
}
if (split >= 0)
label = label.left(split) + ft2m(label.mid(split));
else if (convert)
label = ft2m(label);
QString text(_codec.toString(label));
return Label(capitalize && isAllUpperCase(text) ? capitalized(text) : text,
Shield(shieldType, _codec.toString(shieldLabel)));
}
Label LBLFile::label6b(const SubFile *file, Handle &hdl, bool capitalize,
bool convert) const bool convert) const
{ {
Shield::Type shieldType = Shield::None; Shield::Type shieldType = Shield::None;
@ -147,11 +190,9 @@ Label LBLFile::label6b(Handle &hdl, quint32 offset, bool capitalize,
quint8 b1, b2, b3; quint8 b1, b2, b3;
int split = -1; int split = -1;
if (!seek(hdl, offset))
return Label();
while (true) { while (true) {
if (!(readByte(hdl, &b1) && readByte(hdl, &b2) && readByte(hdl, &b3))) if (!(file->readByte(hdl, &b1) && file->readByte(hdl, &b2)
&& file->readByte(hdl, &b3)))
return Label(); return Label();
int c[]= {b1>>2, (b1&0x3)<<4|b2>>4, (b2&0xF)<<2|b3>>6, b3&0x3F}; int c[]= {b1>>2, (b1&0x3)<<4|b2>>4, (b2&0xF)<<2|b3>>6, b3&0x3F};
@ -203,60 +244,14 @@ Label LBLFile::label6b(Handle &hdl, quint32 offset, bool capitalize,
} }
} }
Label LBLFile::str2label(const QVector<quint8> &str, bool capitalize, Label LBLFile::label8b(const SubFile *file, Handle &hdl, bool capitalize,
bool convert) const
{
Shield::Type shieldType = Shield::None;
QByteArray label, shieldLabel;
QByteArray *bap = &label;
int split = -1;
for (int i = 0; i < str.size(); i++) {
const quint8 &c = str.at(i);
if (c == 0 || c == 0x1d || c == 0x07)
break;
if (c == 0x1c)
capitalize = false;
else if ((c >= 0x1e && c <= 0x1f)) {
if (bap == &shieldLabel)
bap = &label;
else {
if (!bap->isEmpty())
bap->append('\n');
if (c == 0x1f && split < 0)
split = bap->size();
}
} else if (c < 0x07) {
shieldType = static_cast<Shield::Type>(c);
bap = &shieldLabel;
} else if (bap == &shieldLabel && c == 0x20) {
bap = &label;
} else
bap->append(c);
}
if (split >= 0)
label = label.left(split) + ft2m(label.mid(split));
else if (convert)
label = ft2m(label);
QString text(_codec.toString(label));
return Label(capitalize && isAllUpperCase(text) ? capitalized(text) : text,
Shield(shieldType, _codec.toString(shieldLabel)));
}
Label LBLFile::label8b(Handle &hdl, quint32 offset, bool capitalize,
bool convert) const bool convert) const
{ {
QVector<quint8> str; QVector<quint8> str;
quint8 c; quint8 c;
if (!seek(hdl, offset))
return Label();
do { do {
if (!readByte(hdl, &c)) if (!file->readByte(hdl, &c))
return Label(); return Label();
str.append(c); str.append(c);
} while (c); } while (c);
@ -264,15 +259,13 @@ Label LBLFile::label8b(Handle &hdl, quint32 offset, bool capitalize,
return str2label(str, capitalize, convert); return str2label(str, capitalize, convert);
} }
Label LBLFile::labelHuffman(Handle &hdl, quint32 offset, bool capitalize, Label LBLFile::labelHuffman(const SubFile *file, Handle &hdl, bool capitalize,
bool convert) const bool convert) const
{ {
QVector<quint8> str; QVector<quint8> str;
quint32 end = _offset + _size; quint32 end = _offset + _size;
if (!seek(hdl, offset)) if (!_huffmanText->decode(file, hdl, end - pos(hdl), str))
return Label();
if (!_huffmanText->decode(this, hdl, end - offset, str))
return Label(); return Label();
if (!_table) if (!_table)
return str2label(str, capitalize, convert); return str2label(str, capitalize, convert);
@ -291,7 +284,7 @@ Label LBLFile::labelHuffman(Handle &hdl, quint32 offset, bool capitalize,
else if (str2.size()) else if (str2.size())
str2.append(' '); str2.append(' ');
if (!_huffmanText->decode(this, hdl, end - off, str2)) if (!_huffmanText->decode(file, hdl, end - off, str2))
return Label(); return Label();
} else { } else {
if (str.at(i) == 7) { if (str.at(i) == 7) {
@ -324,14 +317,23 @@ Label LBLFile::label(Handle &hdl, quint32 offset, bool poi, bool capitalize,
if (labelOffset > _offset + _size) if (labelOffset > _offset + _size)
return QString(); return QString();
if (!seek(hdl, labelOffset))
return Label();
return label(this, hdl, capitalize, convert);
}
Label LBLFile::label(const SubFile *file, Handle &hdl, bool capitalize,
bool convert) const
{
switch (_encoding) { switch (_encoding) {
case 6: case 6:
return label6b(hdl, labelOffset, capitalize, convert); return label6b(file, hdl, capitalize, convert);
case 9: case 9:
case 10: case 10:
return label8b(hdl, labelOffset, capitalize, convert); return label8b(file, hdl, capitalize, convert);
case 11: case 11:
return labelHuffman(hdl, labelOffset, capitalize, convert); return labelHuffman(file, hdl, capitalize, convert);
default: default:
return Label(); return Label();
} }

View File

@ -33,6 +33,8 @@ public:
Label label(Handle &hdl, quint32 offset, bool poi = false, Label label(Handle &hdl, quint32 offset, bool poi = false,
bool capitalize = true, bool convert = false) const; bool capitalize = true, bool convert = false) const;
Label label(const SubFile *file, Handle &hdl, bool capitalize = true,
bool convert = false) const;
quint8 imageIdSize() const {return _imgOffsetIdSize;} quint8 imageIdSize() const {return _imgOffsetIdSize;}
QPixmap image(Handle &hdl, quint32 id) const; QPixmap image(Handle &hdl, quint32 id) const;
@ -45,11 +47,11 @@ private:
Label str2label(const QVector<quint8> &str, bool capitalize, Label str2label(const QVector<quint8> &str, bool capitalize,
bool convert) const; bool convert) const;
Label label6b(Handle &hdl, quint32 offset, bool capitalize, Label label6b(const SubFile *file, Handle &hdl, bool capitalize,
bool convert) const; bool convert) const;
Label label8b(Handle &hdl, quint32 offset, bool capitalize, Label label8b(const SubFile *file, Handle &hdl, bool capitalize,
bool convert) const; bool convert) const;
Label labelHuffman(Handle &hdl, quint32 offset, bool capitalize, Label labelHuffman(const SubFile *file, Handle &hdl, bool capitalize,
bool convert) const; bool convert) const;
bool loadRasterTable(Handle &hdl, quint32 offset, quint32 size, bool loadRasterTable(Handle &hdl, quint32 offset, quint32 size,
quint32 recordSize); quint32 recordSize);

View File

@ -38,12 +38,13 @@ public:
}; };
struct Point { struct Point {
Point() : id(0) {} Point() : id(0), classLabel(false) {}
Coordinates coordinates; Coordinates coordinates;
Label label; Label label;
quint32 type; quint32 type;
quint64 id; quint64 id;
bool classLabel;
bool operator<(const Point &other) const bool operator<(const Point &other) const
{return id < other.id;} {return id < other.id;}

View File

@ -54,10 +54,16 @@ static QFont *font(Style::FontSize size, Style::FontSize defaultSize
} }
} }
static QFont *poiFont(Style::FontSize size = Style::Normal) static QFont *poiFont(Style::FontSize size = Style::Normal, int zoom = -1,
bool extended = false)
{ {
static QFont poi = pixelSizeFont(10); static QFont poi = pixelSizeFont(10);
if (zoom > 25)
size = Style::Normal;
else if (extended)
size = Style::None;
switch (size) { switch (size) {
case Style::None: case Style::None:
return 0; return 0;
@ -435,7 +441,7 @@ void RasterTile::processPoints(QList<TextItem*> &textItems)
? 0 : &(point.label.text()); ? 0 : &(point.label.text());
const QImage *img = style.img().isNull() ? 0 : &style.img(); const QImage *img = style.img().isNull() ? 0 : &style.img();
const QFont *fnt = poi const QFont *fnt = poi
? poiFont(_zoom > 25 ? Style::Normal : style.textFontSize()) ? poiFont(style.textFontSize(), _zoom, point.classLabel)
: font(style.textFontSize()); : font(style.textFontSize());
const QColor *color = style.textColor().isValid() const QColor *color = style.textColor().isValid()
? &style.textColor() : &textColor; ? &style.textColor() : &textColor;

View File

@ -33,10 +33,14 @@ RGNFile::~RGNFile()
} }
bool RGNFile::readClassFields(Handle &hdl, SegmentType segmentType, bool RGNFile::readClassFields(Handle &hdl, SegmentType segmentType,
MapData::Poly *poly, const LBLFile *lbl) const void *object, const LBLFile *lbl) const
{ {
quint8 flags; quint8 flags;
quint32 rs; quint32 rs;
MapData::Poly *poly = (segmentType == Polygon)
? (MapData::Poly *) object : 0;
MapData::Point *point = (segmentType == Point)
? (MapData::Point *) object : 0;
if (!readByte(hdl, &flags)) if (!readByte(hdl, &flags))
return false; return false;
@ -60,8 +64,7 @@ bool RGNFile::readClassFields(Handle &hdl, SegmentType segmentType,
break; break;
} }
if (segmentType == Polygon && Style::isRaster(poly->type) && lbl if (poly && Style::isRaster(poly->type) && lbl && lbl->imageIdSize()) {
&& lbl->imageIdSize()) {
quint32 id; quint32 id;
quint32 top, right, bottom, left; quint32 top, right, bottom, left;
@ -78,6 +81,14 @@ bool RGNFile::readClassFields(Handle &hdl, SegmentType segmentType,
rs -= lbl->imageIdSize() + 16; rs -= lbl->imageIdSize() + 16;
} }
if (point && (flags & 1) && lbl) {
quint32 p = pos(hdl);
point->label = lbl->label(this, hdl);
point->classLabel = true;
rs -= (pos(hdl) - p);
}
return seek(hdl, pos(hdl) + rs); return seek(hdl, pos(hdl) + rs);
} }
@ -431,9 +442,11 @@ bool RGNFile::extPointObjects(Handle &hdl, const SubDiv *subdiv,
&& readInt16(hdl, lon) && readInt16(hdl, lat))) && readInt16(hdl, lon) && readInt16(hdl, lat)))
return false; return false;
point.type = 0x10000 | (((quint32)type)<<8) | (subtype & 0x1F);
if (subtype & 0x20 && !readUInt24(hdl, labelPtr)) if (subtype & 0x20 && !readUInt24(hdl, labelPtr))
return false; return false;
if (subtype & 0x80 && !readClassFields(hdl, Point)) if (subtype & 0x80 && !readClassFields(hdl, Point, &point, lbl))
return false; return false;
if (subtype & 0x40 && !skipLclFields(hdl, _pointsLclFlags)) if (subtype & 0x40 && !skipLclFields(hdl, _pointsLclFlags))
return false; return false;
@ -443,7 +456,6 @@ bool RGNFile::extPointObjects(Handle &hdl, const SubDiv *subdiv,
QPoint pos(subdiv->lon() + LS(lon, 24-subdiv->bits()), QPoint pos(subdiv->lon() + LS(lon, 24-subdiv->bits()),
subdiv->lat() + LS(lat, 24-subdiv->bits())); subdiv->lat() + LS(lat, 24-subdiv->bits()));
point.type = 0x10000 | (((quint32)type)<<8) | (subtype & 0x1F);
// Discard NT points breaking style draw order logic (and causing huge // Discard NT points breaking style draw order logic (and causing huge
// performance drawback) // performance drawback)
if (point.type == 0x11400) if (point.type == 0x11400)

View File

@ -62,8 +62,8 @@ public:
private: private:
bool segments(Handle &hdl, SubDiv *subdiv, SubDiv::Segment seg[5]) const; bool segments(Handle &hdl, SubDiv *subdiv, SubDiv::Segment seg[5]) const;
bool readClassFields(Handle &hdl, SegmentType segmentType, bool readClassFields(Handle &hdl, SegmentType segmentType, void *object,
MapData::Poly *poly = 0, const LBLFile *lbl = 0) const; const LBLFile *lbl) 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;