1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-11-28 05:34:47 +01:00

Improved country names labels handling

This commit is contained in:
Martin Tůma 2020-02-16 12:57:40 +01:00
parent 26229e5871
commit e4ac9fda0e
4 changed files with 71 additions and 47 deletions

View File

@ -30,15 +30,20 @@ static quint8 SPECIAL_CHARS[] = {
'8', '9', '~', '~', '~', '~', '~', '~' '8', '9', '~', '~', '~', '~', '~', '~'
}; };
static QString capitalize(const QString &str) static bool isAllUpperCase(const QString &str)
{ {
if (str.isEmpty()) if (str.isEmpty())
return str; return false;
for (int i = 0; i < str.size(); i++) for (int i = 0; i < str.size(); i++)
if (str.at(i).isLetter() && !(str.at(i).isUpper() if (str.at(i).isLetter() && !(str.at(i).isUpper()
|| str.at(i) == QChar(0x00DF))) || str.at(i) == QChar(0x00DF)))
return str; return false;
return true;
}
static QString capitalized(const QString &str)
{
QString ret(str); QString ret(str);
for (int i = 0; i < str.size(); i++) for (int i = 0; i < str.size(); i++)
if (i && !str.at(i-1).isSpace()) if (i && !str.at(i-1).isSpace())
@ -77,7 +82,7 @@ bool LBLFile::init(Handle &hdl)
return true; return true;
} }
Label LBLFile::label6b(Handle &hdl, quint32 offset) const Label LBLFile::label6b(Handle &hdl, quint32 offset, bool capitalize) const
{ {
Label::Shield::Type shieldType = Label::Shield::None; Label::Shield::Type shieldType = Label::Shield::None;
QByteArray label, shieldLabel; QByteArray label, shieldLabel;
@ -95,9 +100,12 @@ Label LBLFile::label6b(Handle &hdl, quint32 offset) const
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};
for (int cpt = 0; cpt < 4; cpt++) { for (int cpt = 0; cpt < 4; cpt++) {
if (c[cpt] > 0x2f || (curCharSet == Normal && c[cpt] == 0x1d)) if (c[cpt] > 0x2f || (curCharSet == Normal && c[cpt] == 0x1d)) {
return Label(capitalize(QString::fromLatin1(label)), QString text(QString::fromLatin1(label));
Label::Shield(shieldType, shieldLabel)); return Label(capitalize & isAllUpperCase(text)
? capitalized(text) : text, Label::Shield(shieldType,
shieldLabel));
}
switch (curCharSet) { switch (curCharSet) {
case Normal: case Normal:
if (c[cpt] == 0x1c) if (c[cpt] == 0x1c)
@ -127,7 +135,7 @@ Label LBLFile::label6b(Handle &hdl, quint32 offset) const
} }
} }
Label LBLFile::label8b(Handle &hdl, quint32 offset) const Label LBLFile::label8b(Handle &hdl, quint32 offset, bool capitalize) const
{ {
Label::Shield::Type shieldType = Label::Shield::None; Label::Shield::Type shieldType = Label::Shield::None;
QByteArray label, shieldLabel; QByteArray label, shieldLabel;
@ -157,12 +165,15 @@ Label LBLFile::label8b(Handle &hdl, quint32 offset) const
bap->append(c); bap->append(c);
} }
return Label(capitalize(_codec ? _codec->toUnicode(label) QString text(_codec ? _codec->toUnicode(label) : QString::fromLatin1(label));
: QString::fromLatin1(label)), Label::Shield(shieldType, _codec QString shieldText(_codec ? _codec->toUnicode(shieldLabel)
? _codec->toUnicode(shieldLabel) : QString::fromLatin1(shieldLabel))); : QString::fromLatin1(shieldLabel));
return Label(capitalize && isAllUpperCase(text) ? capitalized(text) : text,
Label::Shield(shieldType, shieldText));
} }
Label LBLFile::label(Handle &hdl, quint32 offset, bool poi) Label LBLFile::label(Handle &hdl, quint32 offset, bool poi, bool capitalize)
{ {
if (!_multiplier && !init(hdl)) if (!_multiplier && !init(hdl))
return QString(); return QString();
@ -183,10 +194,10 @@ Label LBLFile::label(Handle &hdl, quint32 offset, bool poi)
switch (_encoding) { switch (_encoding) {
case 6: case 6:
return label6b(hdl, labelOffset); return label6b(hdl, labelOffset, capitalize);
case 9: case 9:
case 10: case 10:
return label8b(hdl, labelOffset); return label8b(hdl, labelOffset, capitalize);
default: default:
return Label(); return Label();
} }

View File

@ -19,13 +19,14 @@ public:
_codec(0), _offset(0), _size(0), _poiOffset(0), _poiSize(0), _codec(0), _offset(0), _size(0), _poiOffset(0), _poiSize(0),
_poiMultiplier(0), _multiplier(0), _encoding(0) {} _poiMultiplier(0), _multiplier(0), _encoding(0) {}
Label label(Handle &hdl, quint32 offset, bool poi = false); Label label(Handle &hdl, quint32 offset, bool poi = false,
bool capitalize = true);
private: private:
bool init(Handle &hdl); bool init(Handle &hdl);
Label label6b(Handle &hdl, quint32 offset) const; Label label6b(Handle &hdl, quint32 offset, bool capitalize) const;
Label label8b(Handle &hdl, quint32 offset) const; Label label8b(Handle &hdl, quint32 offset, bool capitalize) const;
QTextCodec *_codec; QTextCodec *_codec;
quint32 _offset; quint32 _offset;

View File

@ -8,6 +8,20 @@
#include "rgnfile.h" #include "rgnfile.h"
static quint64 pointId(qint32 x, qint32 y, quint32 type, quint32 labelPtr)
{
quint64 id;
uint hash = qHash(QPair<uint,uint>(qHash(QPair<qint32, qint32>(x, y)),
labelPtr & 0x3FFFFF));
id = ((quint64)type)<<32 | hash;
// Make country labels precedent over city labels
if (!(type >= 0x1400 && type <= 0x153f))
id |= 1ULL<<63;
return id;
}
bool RGNFile::skipClassFields(Handle &hdl) const bool RGNFile::skipClassFields(Handle &hdl) const
{ {
quint8 flags; quint8 flags;
@ -300,9 +314,6 @@ bool RGNFile::pointObjects(Handle &hdl, const SubDiv *subdiv,
SegmentType segmentType, LBLFile *lbl, Handle &lblHdl, SegmentType segmentType, LBLFile *lbl, Handle &lblHdl,
QList<IMG::Point> *points) const QList<IMG::Point> *points) const
{ {
quint8 type, subtype;
qint16 lon, lat;
quint32 labelPtr;
const SubDiv::Segment &segment = (segmentType == IndexedPoint) const SubDiv::Segment &segment = (segmentType == IndexedPoint)
? subdiv->idxPoints() : subdiv->points(); ? subdiv->idxPoints() : subdiv->points();
@ -313,6 +324,9 @@ bool RGNFile::pointObjects(Handle &hdl, const SubDiv *subdiv,
while (hdl.pos() < (int)segment.end()) { while (hdl.pos() < (int)segment.end()) {
IMG::Point point; IMG::Point point;
quint8 type, subtype;
qint16 lon, lat;
quint32 labelPtr;
if (!(readUInt8(hdl, type) && readUInt24(hdl, labelPtr) if (!(readUInt8(hdl, type) && readUInt24(hdl, labelPtr)
&& readInt16(hdl, lon) && readInt16(hdl, lat))) && readInt16(hdl, lon) && readInt16(hdl, lat)))
@ -323,20 +337,16 @@ bool RGNFile::pointObjects(Handle &hdl, const SubDiv *subdiv,
} else } else
subtype = 0; subtype = 0;
QPoint pos(subdiv->lon() + LS(lon, 24-subdiv->bits()),
subdiv->lat() + LS(lat, 24-subdiv->bits()));
point.type = (quint16)type<<8 | subtype; point.type = (quint16)type<<8 | subtype;
point.coordinates = Coordinates(toWGS24(pos.x()), toWGS24(pos.y()));
qint32 lonOffset = LS(lon, 24-subdiv->bits()); point.id = pointId(pos.x(), pos.y(), point.type, labelPtr & 0x3FFFFF);
qint32 latOffset = LS(lat, 24-subdiv->bits());
point.coordinates = Coordinates(toWGS24(subdiv->lon() + lonOffset),
toWGS24(subdiv->lat() + latOffset));
uint hash = qHash(QPair<uint,uint>(qHash(QPair<qint32, qint32>
(subdiv->lon() + lonOffset, subdiv->lat() + latOffset)),
labelPtr & 0x3FFFFF));
point.id = ((quint64)point.type)<<32 | hash;
point.poi = labelPtr & 0x400000; point.poi = labelPtr & 0x400000;
if (lbl && (labelPtr & 0x3FFFFF)) if (lbl && (labelPtr & 0x3FFFFF))
point.label = lbl->label(lblHdl, labelPtr & 0x3FFFFF, point.poi); point.label = lbl->label(lblHdl, labelPtr & 0x3FFFFF, point.poi,
!(point.type == 0x1400 || point.type == 0x1500));
points->append(point); points->append(point);
} }
@ -347,12 +357,8 @@ bool RGNFile::pointObjects(Handle &hdl, const SubDiv *subdiv,
bool RGNFile::extPointObjects(Handle &hdl, const SubDiv *subdiv, LBLFile *lbl, bool RGNFile::extPointObjects(Handle &hdl, const SubDiv *subdiv, LBLFile *lbl,
Handle &lblHdl, QList<IMG::Point> *points) const Handle &lblHdl, QList<IMG::Point> *points) const
{ {
quint8 type, subtype;
qint16 lon, lat;
quint32 labelPtr;
const SubDiv::Segment &segment = subdiv->extPoints(); const SubDiv::Segment &segment = subdiv->extPoints();
if (!segment.isValid()) if (!segment.isValid())
return true; return true;
if (!seek(hdl, segment.offset())) if (!seek(hdl, segment.offset()))
@ -360,19 +366,14 @@ bool RGNFile::extPointObjects(Handle &hdl, const SubDiv *subdiv, LBLFile *lbl,
while (hdl.pos() < (int)segment.end()) { while (hdl.pos() < (int)segment.end()) {
IMG::Point point; IMG::Point point;
qint16 lon, lat;
quint8 type, subtype;
quint32 labelPtr = 0;
if (!(readUInt8(hdl, type) && readUInt8(hdl, subtype) if (!(readUInt8(hdl, type) && readUInt8(hdl, subtype)
&& readInt16(hdl, lon) && readInt16(hdl, lat))) && readInt16(hdl, lon) && readInt16(hdl, lat)))
return false; return false;
point.type = 0x10000 | (((quint32)type)<<8) | (subtype & 0x1F);
qint32 lonOffset = LS(lon, 24-subdiv->bits());
qint32 latOffset = LS(lat, 24-subdiv->bits());
point.coordinates = Coordinates(toWGS24(subdiv->lon() + lonOffset),
toWGS24(subdiv->lat() + latOffset));
labelPtr = 0;
if (subtype & 0x20 && !readUInt24(hdl, labelPtr)) if (subtype & 0x20 && !readUInt24(hdl, labelPtr))
return false; return false;
if (subtype & 0x80 && !skipClassFields(hdl)) if (subtype & 0x80 && !skipClassFields(hdl))
@ -380,15 +381,17 @@ bool RGNFile::extPointObjects(Handle &hdl, const SubDiv *subdiv, LBLFile *lbl,
if (subtype & 0x40 && !skipLclFields(hdl, _pointsFlags, Point)) if (subtype & 0x40 && !skipLclFields(hdl, _pointsFlags, Point))
return false; return false;
QPoint pos(subdiv->lon() + LS(lon, 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)
continue; continue;
uint hash = qHash(QPair<uint,uint>(qHash(QPair<qint32, qint32> point.coordinates = Coordinates(toWGS24(pos.x()), toWGS24(pos.y()));
(subdiv->lon() + lonOffset, subdiv->lat() + latOffset)), point.id = pointId(pos.x(), pos.y(), point.type, labelPtr & 0x3FFFFF);
labelPtr & 0x3FFFFF));
point.id = ((quint64)point.type)<<32 | hash;
point.poi = labelPtr & 0x400000; point.poi = labelPtr & 0x400000;
if (lbl && (labelPtr & 0x3FFFFF)) if (lbl && (labelPtr & 0x3FFFFF))
point.label = lbl->label(lblHdl, labelPtr & 0x3FFFFF, point.poi); point.label = lbl->label(lblHdl, labelPtr & 0x3FFFFF, point.poi);

View File

@ -145,6 +145,15 @@ void Style::defaultLineStyle()
void Style::defaultPointStyle() void Style::defaultPointStyle()
{ {
// Countries
_points[TYPE(0x14)].setTextColor(QColor("#777777"));
_points[TYPE(0x14)].setTextFontSize(Small);
_points[TYPE(0x15)].setTextColor(QColor("#777777"));
_points[TYPE(0x15)].setTextFontSize(Small);
// Regions
_points[TYPE(0x28)].setTextFontSize(Small);
// Cities // Cities
_points[TYPE(0x01)].setTextFontSize(Large); _points[TYPE(0x01)].setTextFontSize(Large);
_points[TYPE(0x02)].setTextFontSize(Large); _points[TYPE(0x02)].setTextFontSize(Large);