mirror of
https://github.com/tumic0/GPXSee.git
synced 2024-11-30 22:51:16 +01:00
Improved country names labels handling
This commit is contained in:
parent
26229e5871
commit
e4ac9fda0e
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user