Merge branch 'master' into android-latest
@ -118,6 +118,7 @@ HEADERS += src/common/config.h \
|
|||||||
src/data/gpsdumpparser.h \
|
src/data/gpsdumpparser.h \
|
||||||
src/data/style.h \
|
src/data/style.h \
|
||||||
src/data/twonavparser.h \
|
src/data/twonavparser.h \
|
||||||
|
src/map/IMG/lights.h \
|
||||||
src/map/downloader.h \
|
src/map/downloader.h \
|
||||||
src/map/demloader.h \
|
src/map/demloader.h \
|
||||||
src/map/ENC/attributes.h \
|
src/map/ENC/attributes.h \
|
||||||
|
@ -193,6 +193,10 @@
|
|||||||
<file alias="overfalls.png">icons/map/marine/overfalls.png</file>
|
<file alias="overfalls.png">icons/map/marine/overfalls.png</file>
|
||||||
<file alias="boarding-place.png">icons/map/marine/boarding-place.png</file>
|
<file alias="boarding-place.png">icons/map/marine/boarding-place.png</file>
|
||||||
<file alias="light.png">icons/map/marine/light.png</file>
|
<file alias="light.png">icons/map/marine/light.png</file>
|
||||||
|
<file alias="light-red.png">icons/map/marine/light-red.png</file>
|
||||||
|
<file alias="light-green.png">icons/map/marine/light-green.png</file>
|
||||||
|
<file alias="light-yellow.png">icons/map/marine/light-yellow.png</file>
|
||||||
|
<file alias="light-white.png">icons/map/marine/light-white.png</file>
|
||||||
<file alias="building.png">icons/map/marine/building.png</file>
|
<file alias="building.png">icons/map/marine/building.png</file>
|
||||||
<file alias="fog-signal.png">icons/map/marine/fog-signal.png</file>
|
<file alias="fog-signal.png">icons/map/marine/fog-signal.png</file>
|
||||||
<file alias="construction.png">icons/map/marine/construction.png</file>
|
<file alias="construction.png">icons/map/marine/construction.png</file>
|
||||||
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.5 KiB |
BIN
icons/map/marine/light-green.png
Normal file
After Width: | Height: | Size: 466 B |
BIN
icons/map/marine/light-red.png
Normal file
After Width: | Height: | Size: 417 B |
BIN
icons/map/marine/light-white.png
Normal file
After Width: | Height: | Size: 330 B |
BIN
icons/map/marine/light-yellow.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 139 B After Width: | Height: | Size: 212 B |
@ -6,6 +6,7 @@
|
|||||||
#define CATDIS 21
|
#define CATDIS 21
|
||||||
#define CATHAF 30
|
#define CATHAF 30
|
||||||
#define CATLMK 35
|
#define CATLMK 35
|
||||||
|
#define CATLIT 37
|
||||||
#define CATMFA 38
|
#define CATMFA 38
|
||||||
#define CATMOR 40
|
#define CATMOR 40
|
||||||
#define CATTRK 54
|
#define CATTRK 54
|
||||||
@ -16,16 +17,21 @@
|
|||||||
#define CATWAT 69
|
#define CATWAT 69
|
||||||
#define CATWED 70
|
#define CATWED 70
|
||||||
#define CATWRK 71
|
#define CATWRK 71
|
||||||
|
#define COLOUR 75
|
||||||
#define COMCHA 77
|
#define COMCHA 77
|
||||||
#define CURVEL 84
|
#define CURVEL 84
|
||||||
#define DRVAL1 87
|
#define DRVAL1 87
|
||||||
#define ELEVAT 90
|
#define ELEVAT 90
|
||||||
#define FUNCTN 94
|
#define FUNCTN 94
|
||||||
|
#define LITVIS 108
|
||||||
#define OBJNAM 116
|
#define OBJNAM 116
|
||||||
#define ORIENT 117
|
#define ORIENT 117
|
||||||
#define RESTRN 131
|
#define RESTRN 131
|
||||||
|
#define SECTR1 136
|
||||||
|
#define SECTR2 137
|
||||||
#define TRAFIC 172
|
#define TRAFIC 172
|
||||||
#define VALDCO 174
|
#define VALDCO 174
|
||||||
|
#define VALNMR 178
|
||||||
#define VERCLR 181
|
#define VERCLR 181
|
||||||
#define WATLEV 187
|
#define WATLEV 187
|
||||||
|
|
||||||
|
@ -173,19 +173,31 @@ static bool polygonCb(const MapData::Poly *polygon, void *context)
|
|||||||
static bool polygonPointCb(const MapData::Poly *polygon, void *context)
|
static bool polygonPointCb(const MapData::Poly *polygon, void *context)
|
||||||
{
|
{
|
||||||
QList<MapData::Point> *points = (QList<MapData::Point>*)context;
|
QList<MapData::Point> *points = (QList<MapData::Point>*)context;
|
||||||
uint baseType = polygon->type()>>16;
|
uint type = polygon->type();
|
||||||
|
uint baseType = type>>16;
|
||||||
|
|
||||||
if (!polygon->label().isEmpty() || baseType == TSSLPT || baseType == RCTLPT
|
if (baseType == TSSLPT || baseType == RCTLPT || baseType == I_TRNBSN
|
||||||
|| baseType == I_TRNBSN
|
|| baseType == BRIDGE || baseType == I_BRIDGE || baseType == BUAARE
|
||||||
|| polygon->type() == SUBTYPE(ACHARE, 2)
|
|| baseType == RESARE || baseType == I_RESARE || baseType == LNDARE
|
||||||
|| polygon->type() == SUBTYPE(ACHARE, 3)
|
|| baseType == LNDRGN
|
||||||
|| polygon->type() == SUBTYPE(ACHARE, 9)
|
|| type == SUBTYPE(ACHARE, 2) || type == SUBTYPE(ACHARE, 3)
|
||||||
|| polygon->type() == SUBTYPE(I_ACHARE, 2)
|
|| type == SUBTYPE(ACHARE, 9) || type == SUBTYPE(I_ACHARE, 2)
|
||||||
|| polygon->type() == SUBTYPE(I_ACHARE, 3)
|
|| type == SUBTYPE(I_ACHARE, 3) || type == SUBTYPE(I_ACHARE, 9)
|
||||||
|| polygon->type() == SUBTYPE(I_ACHARE, 9)
|
|| type == SUBTYPE(I_BERTHS, 6))
|
||||||
|| polygon->type() == SUBTYPE(I_BERTHS, 6))
|
points->append(MapData::Point(baseType, polygon->bounds().center(),
|
||||||
points->append(MapData::Point(polygon->type(), polygon->bounds().center(),
|
polygon->attributes(), polygon->HUNI()));
|
||||||
polygon->label(), polygon->param()));
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool linePointCb(const MapData::Line *line, void *context)
|
||||||
|
{
|
||||||
|
QList<MapData::Point> *points = (QList<MapData::Point>*)context;
|
||||||
|
uint baseType = line->type()>>16;
|
||||||
|
|
||||||
|
if (baseType == RDOCAL || baseType == I_RDOCAL)
|
||||||
|
points->append(MapData::Point(baseType, line->bounds().center(),
|
||||||
|
line->attributes(), 1));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -207,10 +219,8 @@ static Coordinates point(const ISO8211::Record &r, uint COMF)
|
|||||||
return coordinates(x, y, COMF);
|
return coordinates(x, y, COMF);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint depthLevel(const QByteArray &ba)
|
static uint depthLevel(double minDepth)
|
||||||
{
|
{
|
||||||
double minDepth = ba.isEmpty() ? -1 : ba.toDouble();
|
|
||||||
|
|
||||||
if (minDepth < 0)
|
if (minDepth < 0)
|
||||||
return 0;
|
return 0;
|
||||||
else if (minDepth < 2)
|
else if (minDepth < 2)
|
||||||
@ -275,72 +285,145 @@ static QString weed(uint type)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MapData::Point::Point(uint type, const Coordinates &c, const QString &label,
|
MapData::Point::Point(uint type, const Coordinates &c, const QString &label)
|
||||||
const QVector<QByteArray> ¶ms) : _type(type), _pos(c), _label(label)
|
: _type(SUBTYPE(type, 0)), _pos(c), _label(label)
|
||||||
{
|
{
|
||||||
_id = ((quint64)order(type))<<32 | (uint)qHash(c);
|
_id = ((quint64)order(_type))<<32 | (uint)qHash(c);
|
||||||
|
}
|
||||||
|
|
||||||
if (type>>16 == I_DISMAR && params.size()) {
|
MapData::Point::Point(uint type, const Coordinates &c, const Attributes &attr,
|
||||||
_label = hUnits((type>>8)&0xFF) + " " + QString::fromLatin1(params.at(0));
|
uint HUNI) : _pos(c), _attr(attr)
|
||||||
_type = SUBTYPE(I_DISMAR, type & 0xFF);
|
{
|
||||||
} else if ((type>>16 == I_RDOCAL || type>>16 == RDOCAL) && params.size() > 1) {
|
uint subtype = 0;
|
||||||
if (!params.at(1).isEmpty())
|
|
||||||
_label = QString("VHF ") + QString::fromLatin1(params.at(1));
|
if (type == HRBFAC)
|
||||||
_param = QVariant(params.at(0).toDouble());
|
subtype = CATHAF;
|
||||||
} else if (type>>16 == CURENT && params.size() > 1) {
|
else if (type == I_HRBFAC)
|
||||||
if (!params.at(1).isEmpty())
|
subtype = I_CATHAF;
|
||||||
_label = QString::fromLatin1(params.at(1))
|
else if (type == LNDMRK)
|
||||||
+ QString::fromUtf8("\xE2\x80\x89kt");
|
subtype = CATLMK;
|
||||||
_param = QVariant(params.at(0).toDouble());
|
else if (type == WRECKS)
|
||||||
} else if (type>>16 == I_SISTAT || type>>16 == SISTAT) {
|
subtype = CATWRK;
|
||||||
|
else if (type == MORFAC)
|
||||||
|
subtype = CATMOR;
|
||||||
|
else if (type == UWTROC)
|
||||||
|
subtype = WATLEV;
|
||||||
|
else if (type == BUAARE)
|
||||||
|
subtype = CATBUA;
|
||||||
|
else if (type == SMCFAC)
|
||||||
|
subtype = CATSCF;
|
||||||
|
else if (type == BUISGL)
|
||||||
|
subtype = FUNCTN;
|
||||||
|
else if (type == WATTUR)
|
||||||
|
subtype = CATWAT;
|
||||||
|
else if (type == RDOCAL)
|
||||||
|
subtype = TRAFIC;
|
||||||
|
else if (type == I_RDOCAL)
|
||||||
|
subtype = TRAFIC;
|
||||||
|
else if (type == SILTNK)
|
||||||
|
subtype = CATSIL;
|
||||||
|
else if (type == WEDKLP)
|
||||||
|
subtype = CATWED;
|
||||||
|
else if (type == LIGHTS)
|
||||||
|
subtype = CATLIT;
|
||||||
|
else if (type == I_DISMAR)
|
||||||
|
subtype = CATDIS;
|
||||||
|
|
||||||
|
QList<QByteArray> list(_attr.value(subtype).split(','));
|
||||||
|
std::sort(list.begin(), list.end());
|
||||||
|
_type = SUBTYPE(type, list.first().toUInt());
|
||||||
|
_id = ((quint64)order(_type))<<32 | (uint)qHash(c);
|
||||||
|
_label = QString::fromLatin1(_attr.value(OBJNAM));
|
||||||
|
|
||||||
|
if (type == I_DISMAR) {
|
||||||
|
if (_attr.contains(I_WTWDIS) && _attr.contains(I_HUNITS))
|
||||||
|
_label = hUnits(_attr.value(I_HUNITS).toUInt()) + " "
|
||||||
|
+ QString::fromLatin1(_attr.value(I_WTWDIS));
|
||||||
|
} else if (type == I_RDOCAL || type == RDOCAL) {
|
||||||
|
QByteArray cc(_attr.value(COMCHA));
|
||||||
|
if (!cc.isEmpty())
|
||||||
|
_label = QString("VHF ") + QString::fromLatin1(cc);
|
||||||
|
} else if (type == CURENT) {
|
||||||
|
QByteArray cv(_attr.value(CURVEL));
|
||||||
|
if (!cv.isEmpty())
|
||||||
|
_label = QString::fromLatin1(cv) + QString::fromUtf8("\xE2\x80\x89kt");
|
||||||
|
} else if (type == SISTAT) {
|
||||||
|
if (_label.isEmpty() && _attr.contains(CATSIT))
|
||||||
|
_label = sistat(_attr.value(CATSIT).toUInt());
|
||||||
|
} else if (type == I_SISTAT) {
|
||||||
|
if (_label.isEmpty() && _attr.contains(I_CATSIT))
|
||||||
|
_label = sistat(_attr.value(I_CATSIT).toUInt());
|
||||||
|
} else if (type == WEDKLP) {
|
||||||
if (_label.isEmpty())
|
if (_label.isEmpty())
|
||||||
_label = sistat(type & 0xFF);
|
_label = weed(_type & 0xFF);
|
||||||
_type = TYPE(SISTAT);
|
} else if (type == LNDELV) {
|
||||||
} else if (type>>16 == WEDKLP) {
|
|
||||||
if (_label.isEmpty())
|
if (_label.isEmpty())
|
||||||
_label = weed(type & 0xFF);
|
_label = QString::fromLatin1(_attr.value(ELEVAT))
|
||||||
} else if (type>>16 == LNDELV && params.size()) {
|
|
||||||
if (_label.isEmpty())
|
|
||||||
_label = QString::fromLatin1(params.at(0))
|
|
||||||
+ QString::fromUtf8("\xE2\x80\x89m");
|
+ QString::fromUtf8("\xE2\x80\x89m");
|
||||||
else
|
else
|
||||||
_label += "\n(" + QString::fromLatin1(params.at(0))
|
_label += "\n(" + QString::fromLatin1(_attr.value(ELEVAT))
|
||||||
+ "\xE2\x80\x89m)";
|
+ "\xE2\x80\x89m)";
|
||||||
} else if ((type == TYPE(TSSLPT) || type == TYPE(RCTLPT)) && params.size())
|
} else if (type == BRIDGE || type == I_BRIDGE) {
|
||||||
_param = QVariant(params.at(0).toDouble());
|
double clr = _attr.value(VERCLR).toDouble();
|
||||||
}
|
|
||||||
|
|
||||||
MapData::Point::Point(uint type, const Coordinates &c, const QString &label,
|
|
||||||
const QVariant ¶m) : _type(type), _pos(c), _label(label), _param(param)
|
|
||||||
{
|
|
||||||
_id = ((quint64)order(type))<<32 | (uint)qHash(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
MapData::Poly::Poly(uint type, const Polygon &path, const QString &label,
|
|
||||||
const QVector<QByteArray> ¶ms, uint HUNI) : _type(type), _path(path)
|
|
||||||
{
|
|
||||||
if (type == TYPE(DEPARE) && params.size())
|
|
||||||
_type = SUBTYPE(DEPARE, depthLevel(params.at(0)));
|
|
||||||
else if ((type == TYPE(TSSLPT) || type == TYPE(RCTLPT)) && params.size())
|
|
||||||
_param = QVariant(params.at(0).toDouble());
|
|
||||||
else if ((type == TYPE(BRIDGE) || type == TYPE(I_BRIDGE))
|
|
||||||
&& params.size()) {
|
|
||||||
double clr = params.at(0).toDouble();
|
|
||||||
if (clr > 0) {
|
if (clr > 0) {
|
||||||
_label = QString::fromUtf8("\xE2\x86\x95") + UNIT_SPACE
|
_label = QString::fromUtf8("\xE2\x86\x95") + UNIT_SPACE
|
||||||
+ QString::number(clr) + UNIT_SPACE + hUnits(HUNI);
|
+ QString::number(clr) + UNIT_SPACE + hUnits(HUNI);
|
||||||
}
|
}
|
||||||
} else if (type>>16 == LNDARE || type>>16 == SEAARE || type>>16 == BERTHS
|
}
|
||||||
|| type>>16 == I_BERTHS || type>>16 == BUAARE)
|
}
|
||||||
_label = label;
|
|
||||||
|
MapData::Poly::Poly(uint type, const Polygon &path, const Attributes &attr,
|
||||||
|
uint HUNI) : _path(path), _attr(attr), _HUNI(HUNI)
|
||||||
|
{
|
||||||
|
uint subtype = 0;
|
||||||
|
|
||||||
|
if (type == RESARE || type == I_RESARE)
|
||||||
|
subtype = CATREA;
|
||||||
|
else if (type == ACHARE)
|
||||||
|
subtype = CATACH;
|
||||||
|
else if (type == I_ACHARE)
|
||||||
|
subtype = I_CATACH;
|
||||||
|
else if (type == HRBFAC)
|
||||||
|
subtype = CATHAF;
|
||||||
|
else if (type == MARKUL)
|
||||||
|
subtype = CATMFA;
|
||||||
|
else if (type == I_BERTHS)
|
||||||
|
subtype = I_CATBRT;
|
||||||
|
else if (type == RESARE || type == I_RESARE) {
|
||||||
|
uint restr = _attr.value((type == RESARE) ? RESTRN : I_RESTRN).toUInt();
|
||||||
|
if (restr == 1)
|
||||||
|
subtype = 2;
|
||||||
|
else if (restr == 7)
|
||||||
|
subtype = 17;
|
||||||
|
}
|
||||||
|
|
||||||
|
_type = (type == DEPARE)
|
||||||
|
? SUBTYPE(DEPARE, depthLevel(_attr.value(DRVAL1).toDouble()))
|
||||||
|
: SUBTYPE(type, _attr.value(subtype).toUInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
MapData::Line::Line(uint type, const QVector<Coordinates> &path,
|
MapData::Line::Line(uint type, const QVector<Coordinates> &path,
|
||||||
const QString &label, const QVector<QByteArray> ¶ms)
|
const Attributes &attr) : _path(path), _attr(attr)
|
||||||
: _type(type), _path(path), _label(label)
|
|
||||||
{
|
{
|
||||||
if ((type == TYPE(DEPCNT) || type == TYPE(LNDELV)) && params.size())
|
uint subtype = 0;
|
||||||
_label = QString::fromLatin1(params.at(0));
|
|
||||||
|
if (type == RECTRC)
|
||||||
|
subtype = CATTRK;
|
||||||
|
else if (type == RCRTCL)
|
||||||
|
subtype = CATTRK;
|
||||||
|
else if (type == RDOCAL)
|
||||||
|
subtype = TRAFIC;
|
||||||
|
else if (type == I_RDOCAL)
|
||||||
|
subtype = TRAFIC;
|
||||||
|
|
||||||
|
_type = SUBTYPE(type, _attr.value(subtype).toUInt());
|
||||||
|
|
||||||
|
if (type == DEPCNT)
|
||||||
|
_label = QString::fromLatin1(_attr.value(VALDCO));
|
||||||
|
else if (type == LNDELV)
|
||||||
|
_label = QString::fromLatin1(_attr.value(ELEVAT));
|
||||||
|
else
|
||||||
|
_label = QString::fromLatin1(_attr.value(OBJNAM));
|
||||||
}
|
}
|
||||||
|
|
||||||
RectC MapData::Line::bounds() const
|
RectC MapData::Line::bounds() const
|
||||||
@ -581,169 +664,46 @@ Polygon MapData::polyGeometry(const ISO8211::Record &r, const RecordMap &vc,
|
|||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
MapData::Attr MapData::pointAttr(const ISO8211::Record &r, uint OBJL)
|
MapData::Attributes MapData::attributes(const ISO8211::Record &r)
|
||||||
{
|
{
|
||||||
QString label;
|
Attributes attr;
|
||||||
QVector<QByteArray> params(2);
|
|
||||||
uint subtype = 0;
|
|
||||||
|
|
||||||
const ISO8211::Field *ATTF = ISO8211::field(r, "ATTF");
|
const ISO8211::Field *ATTF = ISO8211::field(r, "ATTF");
|
||||||
if (!(ATTF && ATTF->data().at(0).size() == 2))
|
if (!(ATTF && ATTF->data().at(0).size() == 2))
|
||||||
return Attr();
|
return attr;
|
||||||
|
|
||||||
for (int i = 0; i < ATTF->data().size(); i++) {
|
for (int i = 0; i < ATTF->data().size(); i++) {
|
||||||
const QVector<QVariant> &av = ATTF->data().at(i);
|
const QVector<QVariant> &av = ATTF->data().at(i);
|
||||||
uint key = av.at(0).toUInt();
|
attr.insert(av.at(0).toUInt(), av.at(1).toByteArray());
|
||||||
|
|
||||||
if (key == OBJNAM)
|
|
||||||
label = QString::fromLatin1(av.at(1).toByteArray());
|
|
||||||
|
|
||||||
if ((OBJL == HRBFAC && key == CATHAF)
|
|
||||||
|| (OBJL == I_HRBFAC && key == I_CATHAF)
|
|
||||||
|| (OBJL == LNDMRK && key == CATLMK)
|
|
||||||
|| (OBJL == WRECKS && key == CATWRK)
|
|
||||||
|| (OBJL == MORFAC && key == CATMOR)
|
|
||||||
|| (OBJL == UWTROC && key == WATLEV)
|
|
||||||
|| (OBJL == BUAARE && key == CATBUA)
|
|
||||||
|| (OBJL == SMCFAC && key == CATSCF)
|
|
||||||
|| (OBJL == BUISGL && key == FUNCTN)
|
|
||||||
|| (OBJL == WATTUR && key == CATWAT)
|
|
||||||
|| (OBJL == SISTAT && key == CATSIT)
|
|
||||||
|| (OBJL == I_SISTAT && key == I_CATSIT)
|
|
||||||
|| (OBJL == RDOCAL && key == TRAFIC)
|
|
||||||
|| (OBJL == I_RDOCAL && key == TRAFIC)
|
|
||||||
|| (OBJL == SILTNK && key == CATSIL)
|
|
||||||
|| (OBJL == WEDKLP && key == CATWED))
|
|
||||||
subtype = av.at(1).toByteArray().toUInt();
|
|
||||||
else if (OBJL == I_DISMAR && key == CATDIS)
|
|
||||||
subtype |= av.at(1).toByteArray().toUInt();
|
|
||||||
else if (OBJL == I_DISMAR && key == I_HUNITS)
|
|
||||||
subtype |= av.at(1).toByteArray().toUInt() << 8;
|
|
||||||
|
|
||||||
if ((OBJL == I_DISMAR && key == I_WTWDIS)
|
|
||||||
|| (OBJL == RDOCAL && key == ORIENT)
|
|
||||||
|| (OBJL == I_RDOCAL && key == ORIENT)
|
|
||||||
|| (OBJL == CURENT && key == ORIENT)
|
|
||||||
|| (OBJL == LNDELV && key == ELEVAT)
|
|
||||||
|| (OBJL == TSSLPT && key == ORIENT)
|
|
||||||
|| (OBJL == RCTLPT && key == ORIENT))
|
|
||||||
params[0] = av.at(1).toByteArray();
|
|
||||||
if ((OBJL == I_RDOCAL && key == COMCHA)
|
|
||||||
|| (OBJL == RDOCAL && key == COMCHA)
|
|
||||||
|| (OBJL == CURENT && key == CURVEL))
|
|
||||||
params[1] = av.at(1).toByteArray();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Attr(subtype, label, params);
|
return attr;
|
||||||
}
|
|
||||||
|
|
||||||
MapData::Attr MapData::lineAttr(const ISO8211::Record &r, uint OBJL)
|
|
||||||
{
|
|
||||||
QString label;
|
|
||||||
QVector<QByteArray> params(1);
|
|
||||||
uint subtype = 0;
|
|
||||||
|
|
||||||
const ISO8211::Field *ATTF = ISO8211::field(r, "ATTF");
|
|
||||||
if (!(ATTF && ATTF->data().at(0).size() == 2))
|
|
||||||
return Attr();
|
|
||||||
|
|
||||||
for (int i = 0; i < ATTF->data().size(); i++) {
|
|
||||||
const QVector<QVariant> &av = ATTF->data().at(i);
|
|
||||||
uint key = av.at(0).toUInt();
|
|
||||||
|
|
||||||
if (key == OBJNAM)
|
|
||||||
label = QString::fromLatin1(av.at(1).toByteArray());
|
|
||||||
|
|
||||||
if ((OBJL == RECTRC || OBJL == RCRTCL) && key == CATTRK)
|
|
||||||
subtype = av.at(1).toByteArray().toUInt();
|
|
||||||
|
|
||||||
if ((OBJL == DEPCNT && key == VALDCO)
|
|
||||||
|| (OBJL == LNDELV && key == ELEVAT))
|
|
||||||
params[0] = av.at(1).toByteArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
return Attr(subtype, label, params);
|
|
||||||
}
|
|
||||||
|
|
||||||
MapData::Attr MapData::polyAttr(const ISO8211::Record &r, uint OBJL)
|
|
||||||
{
|
|
||||||
QString label;
|
|
||||||
QVector<QByteArray> params(1);
|
|
||||||
uint subtype = 0;
|
|
||||||
|
|
||||||
const ISO8211::Field *ATTF = ISO8211::field(r, "ATTF");
|
|
||||||
if (!(ATTF && ATTF->data().at(0).size() == 2))
|
|
||||||
return Attr();
|
|
||||||
|
|
||||||
for (int i = 0; i < ATTF->data().size(); i++) {
|
|
||||||
const QVector<QVariant> &av = ATTF->data().at(i);
|
|
||||||
uint key = av.at(0).toUInt();
|
|
||||||
|
|
||||||
if (key == OBJNAM)
|
|
||||||
label = QString::fromLatin1(av.at(1).toByteArray());
|
|
||||||
|
|
||||||
if ((OBJL == RESARE && key == CATREA)
|
|
||||||
|| (OBJL == I_RESARE && key == CATREA)
|
|
||||||
|| (OBJL == ACHARE && key == CATACH)
|
|
||||||
|| (OBJL == I_ACHARE && key == I_CATACH)
|
|
||||||
|| (OBJL == HRBFAC && key == CATHAF)
|
|
||||||
|| (OBJL == MARKUL && key == CATMFA)
|
|
||||||
|| (OBJL == I_BERTHS && key == I_CATBRT))
|
|
||||||
subtype = av.at(1).toByteArray().toUInt();
|
|
||||||
else if ((OBJL == RESARE && key == RESTRN)
|
|
||||||
|| (OBJL == I_RESARE && key == I_RESTRN)) {
|
|
||||||
if (av.at(1).toByteArray().toUInt() == 1)
|
|
||||||
subtype = 2;
|
|
||||||
if (av.at(1).toByteArray().toUInt() == 7)
|
|
||||||
subtype = 17;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((OBJL == TSSLPT && key == ORIENT)
|
|
||||||
|| (OBJL == RCTLPT && key == ORIENT)
|
|
||||||
|| (OBJL == DEPARE && key == DRVAL1))
|
|
||||||
params[0] = av.at(1).toByteArray();
|
|
||||||
if ((OBJL == BRIDGE && key == VERCLR)
|
|
||||||
|| (OBJL == I_BRIDGE && key == VERCLR))
|
|
||||||
params[0] = av.at(1).toByteArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
return Attr(subtype, label, params);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MapData::Point *MapData::pointObject(const Sounding &s)
|
MapData::Point *MapData::pointObject(const Sounding &s)
|
||||||
{
|
{
|
||||||
return new Point(TYPE(SOUNDG), s.c, QString::number(s.depth),
|
return new Point(SOUNDG, s.c, QString::number(s.depth));
|
||||||
QVector<QByteArray>());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MapData::Point *MapData::pointObject(const ISO8211::Record &r,
|
MapData::Point *MapData::pointObject(const ISO8211::Record &r,
|
||||||
const RecordMap &vi, const RecordMap &vc, uint COMF, uint OBJL)
|
const RecordMap &vi, const RecordMap &vc, uint COMF, uint OBJL, uint HUNI)
|
||||||
{
|
{
|
||||||
Coordinates c(pointGeometry(r, vi, vc, COMF));
|
Coordinates c(pointGeometry(r, vi, vc, COMF));
|
||||||
Attr attr(pointAttr(r, OBJL));
|
return (c.isNull() ? 0 : new Point(OBJL, c, attributes(r), HUNI));
|
||||||
|
|
||||||
return (c.isNull() ? 0 : new Point(SUBTYPE(OBJL,attr.subtype()), c,
|
|
||||||
attr.label(), attr.params()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MapData::Line *MapData::lineObject(const ISO8211::Record &r,
|
MapData::Line *MapData::lineObject(const ISO8211::Record &r,
|
||||||
const RecordMap &vc, const RecordMap &ve, uint COMF, uint OBJL)
|
const RecordMap &vc, const RecordMap &ve, uint COMF, uint OBJL)
|
||||||
{
|
{
|
||||||
QVector<Coordinates> path(lineGeometry(r, vc, ve, COMF));
|
QVector<Coordinates> path(lineGeometry(r, vc, ve, COMF));
|
||||||
Attr attr(lineAttr(r, OBJL));
|
return (path.isEmpty() ? 0 : new Line(OBJL, path, attributes(r)));
|
||||||
|
|
||||||
return (path.isEmpty() ? 0 : new Line(SUBTYPE(OBJL, attr.subtype()), path,
|
|
||||||
attr.label(), attr.params()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MapData::Poly *MapData::polyObject(const ISO8211::Record &r,
|
MapData::Poly *MapData::polyObject(const ISO8211::Record &r,
|
||||||
const RecordMap &vc, const RecordMap &ve, uint COMF, uint OBJL, uint HUNI)
|
const RecordMap &vc, const RecordMap &ve, uint COMF, uint OBJL, uint HUNI)
|
||||||
{
|
{
|
||||||
Polygon path(polyGeometry(r, vc, ve, COMF));
|
Polygon path(polyGeometry(r, vc, ve, COMF));
|
||||||
Attr attr(polyAttr(r, OBJL));
|
return (path.isEmpty() ? 0 : new Poly(OBJL, path, attributes(r), HUNI));
|
||||||
|
|
||||||
return (path.isEmpty() ? 0 : new Poly(SUBTYPE(OBJL, attr.subtype()), path,
|
|
||||||
attr.label(), attr.params(), HUNI));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MapData::processRecord(const ISO8211::Record &record,
|
bool MapData::processRecord(const ISO8211::Record &record,
|
||||||
@ -828,7 +788,7 @@ MapData::MapData(const QString &path)
|
|||||||
_points.Insert(min, max, point);
|
_points.Insert(min, max, point);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ((point = pointObject(r, vi, vc, COMF, OBJL))) {
|
if ((point = pointObject(r, vi, vc, COMF, OBJL, HUNI))) {
|
||||||
pointBounds(point->pos(), min, max);
|
pointBounds(point->pos(), min, max);
|
||||||
_points.Insert(min, max, point);
|
_points.Insert(min, max, point);
|
||||||
} else
|
} else
|
||||||
@ -875,6 +835,7 @@ void MapData::points(const RectC &rect, QList<Point> *points) const
|
|||||||
rectcBounds(rect, min, max);
|
rectcBounds(rect, min, max);
|
||||||
_points.Search(min, max, pointCb, points);
|
_points.Search(min, max, pointCb, points);
|
||||||
_areas.Search(min, max, polygonPointCb, points);
|
_areas.Search(min, max, polygonPointCb, points);
|
||||||
|
_lines.Search(min, max, linePointCb, points);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapData::lines(const RectC &rect, QList<Line> *lines) const
|
void MapData::lines(const RectC &rect, QList<Line> *lines) const
|
||||||
|
@ -11,51 +11,51 @@ namespace ENC {
|
|||||||
class MapData
|
class MapData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
typedef QMap<uint, QByteArray> Attributes;
|
||||||
|
|
||||||
class Poly {
|
class Poly {
|
||||||
public:
|
public:
|
||||||
Poly(uint type, const Polygon &path, const QString &label,
|
Poly(uint type, const Polygon &path, const Attributes &attr, uint HUNI);
|
||||||
const QVector<QByteArray> ¶ms, uint HUNI);
|
|
||||||
|
|
||||||
RectC bounds() const {return _path.boundingRect();}
|
RectC bounds() const {return _path.boundingRect();}
|
||||||
const Polygon &path() const {return _path;}
|
const Polygon &path() const {return _path;}
|
||||||
uint type() const {return _type;}
|
uint type() const {return _type;}
|
||||||
const QString &label() const {return _label;}
|
const Attributes &attributes() const {return _attr;}
|
||||||
const QVariant ¶m() const {return _param;}
|
uint HUNI() const {return _HUNI;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint _type;
|
uint _type;
|
||||||
Polygon _path;
|
Polygon _path;
|
||||||
QString _label;
|
Attributes _attr;
|
||||||
QVariant _param;
|
uint _HUNI;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Line {
|
class Line {
|
||||||
public:
|
public:
|
||||||
Line(uint type, const QVector<Coordinates> &path, const QString &label,
|
Line(uint type, const QVector<Coordinates> &path, const Attributes &attr);
|
||||||
const QVector<QByteArray> ¶ms);
|
|
||||||
|
|
||||||
RectC bounds() const;
|
RectC bounds() const;
|
||||||
const QVector<Coordinates> &path() const {return _path;}
|
const QVector<Coordinates> &path() const {return _path;}
|
||||||
uint type() const {return _type;}
|
uint type() const {return _type;}
|
||||||
const QString &label() const {return _label;}
|
const QString &label() const {return _label;}
|
||||||
|
const Attributes &attributes() const {return _attr;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint _type;
|
uint _type;
|
||||||
QVector<Coordinates> _path;
|
QVector<Coordinates> _path;
|
||||||
QString _label;
|
QString _label;
|
||||||
|
Attributes _attr;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Point {
|
class Point {
|
||||||
public:
|
public:
|
||||||
Point(uint type, const Coordinates &c, const QString &label,
|
Point(uint type, const Coordinates &c, const Attributes &attr, uint HUNI);
|
||||||
const QVector<QByteArray> ¶ms);
|
Point(uint type, const Coordinates &s, const QString &label);
|
||||||
Point(uint type, const Coordinates &c, const QString &label,
|
|
||||||
const QVariant ¶m);
|
|
||||||
|
|
||||||
const Coordinates &pos() const {return _pos;}
|
const Coordinates &pos() const {return _pos;}
|
||||||
uint type() const {return _type;}
|
uint type() const {return _type;}
|
||||||
const QString &label() const {return _label;}
|
const QString &label() const {return _label;}
|
||||||
const QVariant ¶m() const {return _param;}
|
const Attributes &attributes() const {return _attr;}
|
||||||
|
|
||||||
bool operator<(const Point &other) const
|
bool operator<(const Point &other) const
|
||||||
{return _id < other._id;}
|
{return _id < other._id;}
|
||||||
@ -65,7 +65,7 @@ public:
|
|||||||
Coordinates _pos;
|
Coordinates _pos;
|
||||||
QString _label;
|
QString _label;
|
||||||
quint64 _id;
|
quint64 _id;
|
||||||
QVariant _param;
|
Attributes _attr;
|
||||||
};
|
};
|
||||||
|
|
||||||
MapData(const QString &path);
|
MapData(const QString &path);
|
||||||
@ -76,23 +76,6 @@ public:
|
|||||||
void points(const RectC &rect, QList<Point> *points) const;
|
void points(const RectC &rect, QList<Point> *points) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Attr {
|
|
||||||
public:
|
|
||||||
Attr() : _subtype(0) {}
|
|
||||||
Attr(uint subtype, const QString &label,
|
|
||||||
const QVector<QByteArray> ¶ms)
|
|
||||||
: _subtype(subtype), _label(label), _params(params) {}
|
|
||||||
|
|
||||||
unsigned subtype() const {return _subtype;}
|
|
||||||
const QString &label() const {return _label;}
|
|
||||||
const QVector<QByteArray> ¶ms() const {return _params;}
|
|
||||||
|
|
||||||
private:
|
|
||||||
unsigned _subtype;
|
|
||||||
QString _label;
|
|
||||||
QVector<QByteArray> _params;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Sounding {
|
struct Sounding {
|
||||||
Sounding() : depth(NAN) {}
|
Sounding() : depth(NAN) {}
|
||||||
Sounding(const Coordinates &c, double depth) : c(c), depth(depth) {}
|
Sounding(const Coordinates &c, double depth) : c(c), depth(depth) {}
|
||||||
@ -117,12 +100,10 @@ private:
|
|||||||
const RecordMap &vc, const RecordMap &ve, uint COMF);
|
const RecordMap &vc, const RecordMap &ve, uint COMF);
|
||||||
static Polygon polyGeometry(const ISO8211::Record &r, const RecordMap &vc,
|
static Polygon polyGeometry(const ISO8211::Record &r, const RecordMap &vc,
|
||||||
const RecordMap &ve, uint COMF);
|
const RecordMap &ve, uint COMF);
|
||||||
static Attr pointAttr(const ISO8211::Record &r, uint OBJL);
|
static Attributes attributes(const ISO8211::Record &r);
|
||||||
static Attr lineAttr(const ISO8211::Record &r, uint OBJL);
|
|
||||||
static Attr polyAttr(const ISO8211::Record &r, uint OBJL);
|
|
||||||
static Point *pointObject(const Sounding &s);
|
static Point *pointObject(const Sounding &s);
|
||||||
static Point *pointObject(const ISO8211::Record &r, const RecordMap &vi,
|
static Point *pointObject(const ISO8211::Record &r, const RecordMap &vi,
|
||||||
const RecordMap &vc, uint COMF, uint OBJL);
|
const RecordMap &vc, uint COMF, uint OBJL, uint HUNI);
|
||||||
static Line *lineObject(const ISO8211::Record &r, const RecordMap &vc,
|
static Line *lineObject(const ISO8211::Record &r, const RecordMap &vc,
|
||||||
const RecordMap &ve, uint COMF, uint OBJL);
|
const RecordMap &ve, uint COMF, uint OBJL);
|
||||||
static Poly *polyObject(const ISO8211::Record &r, const RecordMap &vc,
|
static Poly *polyObject(const ISO8211::Record &r, const RecordMap &vc,
|
||||||
|
@ -51,6 +51,7 @@
|
|||||||
#define LAKARE 69
|
#define LAKARE 69
|
||||||
#define LNDARE 71
|
#define LNDARE 71
|
||||||
#define LNDELV 72
|
#define LNDELV 72
|
||||||
|
#define LNDRGN 73
|
||||||
#define LNDMRK 74
|
#define LNDMRK 74
|
||||||
#define LIGHTS 75
|
#define LIGHTS 75
|
||||||
#define LOKBSN 79
|
#define LOKBSN 79
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "map/textpointitem.h"
|
#include "map/textpointitem.h"
|
||||||
#include "map/rectd.h"
|
#include "map/rectd.h"
|
||||||
#include "objects.h"
|
#include "objects.h"
|
||||||
|
#include "attributes.h"
|
||||||
#include "style.h"
|
#include "style.h"
|
||||||
#include "rastertile.h"
|
#include "rastertile.h"
|
||||||
|
|
||||||
@ -12,8 +13,7 @@ using namespace ENC;
|
|||||||
|
|
||||||
#define TEXT_EXTENT 160
|
#define TEXT_EXTENT 160
|
||||||
#define TSSLPT_SIZE 24
|
#define TSSLPT_SIZE 24
|
||||||
|
#define RANGE_FACTOR 4
|
||||||
typedef QSet<Coordinates> PointSet;
|
|
||||||
|
|
||||||
static const float C1 = 0.866025f; /* sqrt(3)/2 */
|
static const float C1 = 0.866025f; /* sqrt(3)/2 */
|
||||||
static const QColor tsslptPen = QColor(0xeb, 0x49, 0xeb);
|
static const QColor tsslptPen = QColor(0xeb, 0x49, 0xeb);
|
||||||
@ -138,21 +138,21 @@ static void drawArrow(QPainter *painter, const QPolygonF &polygon, uint type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RasterTile::drawArrows(QPainter *painter,
|
void RasterTile::drawArrows(QPainter *painter,
|
||||||
const QList<MapData::Point> &points)
|
const QList<MapData::Point> &points) const
|
||||||
{
|
{
|
||||||
for (int i = 0; i < points.size(); i++) {
|
for (int i = 0; i < points.size(); i++) {
|
||||||
const MapData::Point &point = points.at(i);
|
const MapData::Point &point = points.at(i);
|
||||||
|
|
||||||
if (point.type()>>16 == TSSLPT || point.type()>>16 == RCTLPT) {
|
if (point.type()>>16 == TSSLPT || point.type()>>16 == RCTLPT) {
|
||||||
QPolygonF polygon(tsslptArrow(ll2xy(point.pos()),
|
QPolygonF polygon(tsslptArrow(ll2xy(point.pos()),
|
||||||
deg2rad(point.param().toDouble())));
|
deg2rad(point.attributes().value(ORIENT).toDouble())));
|
||||||
drawArrow(painter, polygon, point.type());
|
drawArrow(painter, polygon, point.type());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterTile::drawPolygons(QPainter *painter,
|
void RasterTile::drawPolygons(QPainter *painter,
|
||||||
const QList<MapData::Poly> &polygons)
|
const QList<MapData::Poly> &polygons) const
|
||||||
{
|
{
|
||||||
for (int n = 0; n < _style->drawOrder().size(); n++) {
|
for (int n = 0; n < _style->drawOrder().size(); n++) {
|
||||||
for (int i = 0; i < polygons.size(); i++) {
|
for (int i = 0; i < polygons.size(); i++) {
|
||||||
@ -184,7 +184,7 @@ void RasterTile::drawPolygons(QPainter *painter,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterTile::drawLines(QPainter *painter, const QList<MapData::Line> &lines)
|
void RasterTile::drawLines(QPainter *painter, const QList<MapData::Line> &lines) const
|
||||||
{
|
{
|
||||||
painter->setBrush(Qt::NoBrush);
|
painter->setBrush(Qt::NoBrush);
|
||||||
|
|
||||||
@ -202,7 +202,7 @@ void RasterTile::drawLines(QPainter *painter, const QList<MapData::Line> &lines)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RasterTile::drawTextItems(QPainter *painter,
|
void RasterTile::drawTextItems(QPainter *painter,
|
||||||
const QList<TextItem*> &textItems)
|
const QList<TextItem*> &textItems) const
|
||||||
{
|
{
|
||||||
QRectF rect(_rect);
|
QRectF rect(_rect);
|
||||||
|
|
||||||
@ -213,10 +213,56 @@ void RasterTile::drawTextItems(QPainter *painter,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterTile::processPoints(QList<MapData::Point> &points,
|
static QRectF lightRect(const QPointF &pos, double range)
|
||||||
QList<TextItem*> &textItems, QList<TextItem*> &lights)
|
|
||||||
{
|
{
|
||||||
PointSet lightsSet, signalsSet;
|
return QRectF(pos.x() - range * RANGE_FACTOR, pos.y() - range * RANGE_FACTOR,
|
||||||
|
2*range * RANGE_FACTOR, 2*range * RANGE_FACTOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RasterTile::drawSectorLights(QPainter *painter,
|
||||||
|
const QList<SectorLight> &lights) const
|
||||||
|
{
|
||||||
|
for (int i = 0; i < lights.size(); i++) {
|
||||||
|
const SectorLight &l = lights.at(i);
|
||||||
|
QPointF pos(ll2xy(l.pos));
|
||||||
|
QRectF rect(lightRect(pos, (l.range == 0) ? 6 : l.range));
|
||||||
|
double a1 = -(l.end + 90);
|
||||||
|
double a2 = -(l.start + 90);
|
||||||
|
if (a1 > a2)
|
||||||
|
a2 += 360;
|
||||||
|
double as = (a2 - a1);
|
||||||
|
if (as == 0)
|
||||||
|
as = 360;
|
||||||
|
|
||||||
|
if (l.visibility == 3 || l.visibility >= 6)
|
||||||
|
painter->setPen(QPen(Qt::black, 1, Qt::DashLine));
|
||||||
|
else {
|
||||||
|
painter->setPen(QPen(Qt::black, 6, Qt::SolidLine, Qt::FlatCap));
|
||||||
|
painter->drawArc(rect, a1 * 16, as * 16);
|
||||||
|
painter->setPen(QPen(Style::color(l.color), 4, Qt::SolidLine,
|
||||||
|
Qt::FlatCap));
|
||||||
|
}
|
||||||
|
|
||||||
|
painter->drawArc(rect, a1 * 16, as * 16);
|
||||||
|
|
||||||
|
if (a2 - a1 != 0) {
|
||||||
|
QLineF ln(pos, QPointF(pos.x() + rect.width(), pos.y()));
|
||||||
|
ln.setAngle(a1);
|
||||||
|
painter->setPen(QPen(Qt::black, 1, Qt::DashLine));
|
||||||
|
painter->drawLine(ln);
|
||||||
|
ln.setAngle(a2);
|
||||||
|
painter->drawLine(ln);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RasterTile::processPoints(QList<MapData::Point> &points,
|
||||||
|
QList<TextItem*> &textItems, QList<TextItem*> &lights,
|
||||||
|
QList<SectorLight> §orLights)
|
||||||
|
{
|
||||||
|
LightMap lightsMap;
|
||||||
|
SignalSet signalsSet;
|
||||||
|
QSet<Coordinates> slMap;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
std::sort(points.begin(), points.end());
|
std::sort(points.begin(), points.end());
|
||||||
@ -224,9 +270,22 @@ void RasterTile::processPoints(QList<MapData::Point> &points,
|
|||||||
/* Lights & Signals */
|
/* Lights & Signals */
|
||||||
for (i = 0; i < points.size(); i++) {
|
for (i = 0; i < points.size(); i++) {
|
||||||
const MapData::Point &point = points.at(i);
|
const MapData::Point &point = points.at(i);
|
||||||
if (point.type()>>16 == LIGHTS)
|
|
||||||
lightsSet.insert(point.pos());
|
if (point.type()>>16 == LIGHTS) {
|
||||||
else if (point.type()>>16 == FOGSIG)
|
const MapData::Attributes &attr = point.attributes();
|
||||||
|
Style::Color color = (Style::Color)(attr.value(COLOUR).toUInt());
|
||||||
|
double range = attr.value(VALNMR).toDouble();
|
||||||
|
|
||||||
|
if (attr.contains(SECTR1)
|
||||||
|
|| (range >= 6 && !(point.type() & 0xFFFF))) {
|
||||||
|
sectorLights.append(SectorLight(point.pos(), color,
|
||||||
|
attr.value(LITVIS).toUInt(), range,
|
||||||
|
attr.value(SECTR1).toDouble(), attr.value(SECTR2).toDouble()));
|
||||||
|
slMap.insert(point.pos());
|
||||||
|
qDebug() << attr;
|
||||||
|
} else
|
||||||
|
lightsMap.insert(point.pos(), color);
|
||||||
|
} else if (point.type()>>16 == FOGSIG)
|
||||||
signalsSet.insert(point.pos());
|
signalsSet.insert(point.pos());
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
@ -245,7 +304,7 @@ void RasterTile::processPoints(QList<MapData::Point> &points,
|
|||||||
const QColor *color = &style.textColor();
|
const QColor *color = &style.textColor();
|
||||||
const QColor *hColor = style.haloColor().isValid()
|
const QColor *hColor = style.haloColor().isValid()
|
||||||
? &style.haloColor() : 0;
|
? &style.haloColor() : 0;
|
||||||
double rotate = angle(point.type(), point.param());
|
double rotate = angle(point.type(), point.attributes().value(ORIENT));
|
||||||
|
|
||||||
if ((!label || !fnt) && !img)
|
if ((!label || !fnt) && !img)
|
||||||
continue;
|
continue;
|
||||||
@ -254,11 +313,12 @@ void RasterTile::processPoints(QList<MapData::Point> &points,
|
|||||||
|
|
||||||
TextPointItem *item = new TextPointItem(pos + offset, label, fnt, img,
|
TextPointItem *item = new TextPointItem(pos + offset, label, fnt, img,
|
||||||
color, hColor, 0, 2, rotate);
|
color, hColor, 0, 2, rotate);
|
||||||
if (item->isValid() && !item->collides(textItems)) {
|
if (item->isValid() && (slMap.contains(point.pos())
|
||||||
|
|| !item->collides(textItems))) {
|
||||||
textItems.append(item);
|
textItems.append(item);
|
||||||
if (lightsSet.contains(point.pos()))
|
if (lightsMap.contains(point.pos()))
|
||||||
lights.append(new TextPointItem(pos + _style->lightOffset(),
|
lights.append(new TextPointItem(pos + _style->lightOffset(),
|
||||||
0, 0, _style->light(), 0, 0, 0, 0));
|
0, 0, _style->light(lightsMap.value(point.pos())), 0, 0, 0, 0));
|
||||||
if (signalsSet.contains(point.pos()))
|
if (signalsSet.contains(point.pos()))
|
||||||
lights.append(new TextPointItem(pos + _style->signalOffset(),
|
lights.append(new TextPointItem(pos + _style->signalOffset(),
|
||||||
0, 0, _style->signal(), 0, 0, 0, 0));
|
0, 0, _style->signal(), 0, 0, 0, 0));
|
||||||
@ -326,13 +386,14 @@ void RasterTile::render()
|
|||||||
QList<MapData::Poly> polygons;
|
QList<MapData::Poly> polygons;
|
||||||
QList<MapData::Point> points;
|
QList<MapData::Point> points;
|
||||||
QList<TextItem*> textItems, lights;
|
QList<TextItem*> textItems, lights;
|
||||||
|
QList<SectorLight> sectorLights;
|
||||||
|
|
||||||
img.setDevicePixelRatio(_ratio);
|
img.setDevicePixelRatio(_ratio);
|
||||||
img.fill(Qt::transparent);
|
img.fill(Qt::transparent);
|
||||||
|
|
||||||
fetchData(polygons, lines, points);
|
fetchData(polygons, lines, points);
|
||||||
|
|
||||||
processPoints(points, textItems, lights);
|
processPoints(points, textItems, lights, sectorLights);
|
||||||
processLines(lines, textItems);
|
processLines(lines, textItems);
|
||||||
|
|
||||||
QPainter painter(&img);
|
QPainter painter(&img);
|
||||||
@ -344,7 +405,9 @@ void RasterTile::render()
|
|||||||
drawLines(&painter, lines);
|
drawLines(&painter, lines);
|
||||||
drawArrows(&painter, points);
|
drawArrows(&painter, points);
|
||||||
|
|
||||||
|
|
||||||
drawTextItems(&painter, lights);
|
drawTextItems(&painter, lights);
|
||||||
|
drawSectorLights(&painter, sectorLights);
|
||||||
drawTextItems(&painter, textItems);
|
drawTextItems(&painter, textItems);
|
||||||
|
|
||||||
qDeleteAll(textItems);
|
qDeleteAll(textItems);
|
||||||
|
@ -34,6 +34,23 @@ public:
|
|||||||
void render();
|
void render();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct SectorLight
|
||||||
|
{
|
||||||
|
SectorLight(const Coordinates &pos, Style::Color color, uint visibility,
|
||||||
|
double range, double start, double end) : pos(pos), color(color),
|
||||||
|
visibility(visibility), range(range), start(start), end(end) {}
|
||||||
|
|
||||||
|
Coordinates pos;
|
||||||
|
Style::Color color;
|
||||||
|
uint visibility;
|
||||||
|
double range;
|
||||||
|
double start;
|
||||||
|
double end;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef QMap<Coordinates, Style::Color> LightMap;
|
||||||
|
typedef QSet<Coordinates> SignalSet;
|
||||||
|
|
||||||
void fetchData(QList<MapData::Poly> &polygons, QList<MapData::Line> &lines,
|
void fetchData(QList<MapData::Poly> &polygons, QList<MapData::Line> &lines,
|
||||||
QList<MapData::Point> &points);
|
QList<MapData::Point> &points);
|
||||||
QPointF ll2xy(const Coordinates &c) const
|
QPointF ll2xy(const Coordinates &c) const
|
||||||
@ -44,15 +61,15 @@ private:
|
|||||||
QPolygonF tsslptArrow(const QPointF &p, qreal angle) const;
|
QPolygonF tsslptArrow(const QPointF &p, qreal angle) const;
|
||||||
QPointF centroid(const QVector<Coordinates> &polygon) const;
|
QPointF centroid(const QVector<Coordinates> &polygon) const;
|
||||||
void processPoints(QList<MapData::Point> &points,
|
void processPoints(QList<MapData::Point> &points,
|
||||||
QList<TextItem*> &textItems, QList<TextItem *> &lights);
|
QList<TextItem*> &textItems, QList<TextItem *> &lights,
|
||||||
|
QList<SectorLight> §orLights);
|
||||||
void processLines(const QList<MapData::Line> &lines,
|
void processLines(const QList<MapData::Line> &lines,
|
||||||
QList<TextItem*> &textItems);
|
QList<TextItem*> &textItems);
|
||||||
void drawBitmapPath(QPainter *painter, const QImage &img,
|
void drawArrows(QPainter *painter, const QList<MapData::Point> &points) const;
|
||||||
const Polygon &polygon);
|
void drawPolygons(QPainter *painter, const QList<MapData::Poly> &polygons) const;
|
||||||
void drawArrows(QPainter *painter, const QList<MapData::Point> &points);
|
void drawLines(QPainter *painter, const QList<MapData::Line> &lines) const;
|
||||||
void drawPolygons(QPainter *painter, const QList<MapData::Poly> &polygons);
|
void drawTextItems(QPainter *painter, const QList<TextItem*> &textItems) const;
|
||||||
void drawLines(QPainter *painter, const QList<MapData::Line> &lines);
|
void drawSectorLights(QPainter *painter, const QList<SectorLight> &lights) const;
|
||||||
void drawTextItems(QPainter *painter, const QList<TextItem*> &textItems);
|
|
||||||
|
|
||||||
static bool polyCb(MapData *data, void *context);
|
static bool polyCb(MapData *data, void *context);
|
||||||
static bool pointCb(MapData *data, void *context);
|
static bool pointCb(MapData *data, void *context);
|
||||||
|
@ -222,6 +222,14 @@ void Style::lineStyle(qreal ratio)
|
|||||||
_lines[TYPE(PIPOHD)] = Line(QImage(":/marine/pipeline-overhead.png"));
|
_lines[TYPE(PIPOHD)] = Line(QImage(":/marine/pipeline-overhead.png"));
|
||||||
_lines[TYPE(I_PIPOHD)] = Line(QImage(":/marine/pipeline-overhead.png"));
|
_lines[TYPE(I_PIPOHD)] = Line(QImage(":/marine/pipeline-overhead.png"));
|
||||||
_lines[TYPE(CANALS)] = Line(QPen(QColor(0x9f, 0xc4, 0xe1), 2));
|
_lines[TYPE(CANALS)] = Line(QPen(QColor(0x9f, 0xc4, 0xe1), 2));
|
||||||
|
_lines[SUBTYPE(RDOCAL, 1)] = Line(QPen(QColor(0xeb, 0x49, 0xeb), 1,
|
||||||
|
Qt::DashLine));
|
||||||
|
_lines[SUBTYPE(RDOCAL, 2)] = Line(QPen(QColor(0xeb, 0x49, 0xeb), 1,
|
||||||
|
Qt::DashLine));
|
||||||
|
_lines[SUBTYPE(RDOCAL, 3)] = Line(QPen(QColor(0xeb, 0x49, 0xeb), 1,
|
||||||
|
Qt::DashLine));
|
||||||
|
_lines[SUBTYPE(RDOCAL, 4)] = Line(QPen(QColor(0xeb, 0x49, 0xeb), 1,
|
||||||
|
Qt::DashLine));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Style::pointStyle(qreal ratio)
|
void Style::pointStyle(qreal ratio)
|
||||||
@ -302,7 +310,9 @@ void Style::pointStyle(qreal ratio)
|
|||||||
_points[SUBTYPE(I_HRBFAC, 5)] = Point(QImage(":/marine/yacht-harbor.png"));
|
_points[SUBTYPE(I_HRBFAC, 5)] = Point(QImage(":/marine/yacht-harbor.png"));
|
||||||
_points[SUBTYPE(I_HRBFAC, 9)] = Point(QImage(":/marine/shipyard.png"));
|
_points[SUBTYPE(I_HRBFAC, 9)] = Point(QImage(":/marine/shipyard.png"));
|
||||||
_points[TYPE(ACHBRT)] = Point(QImage(":/marine/anchorage.png"));
|
_points[TYPE(ACHBRT)] = Point(QImage(":/marine/anchorage.png"));
|
||||||
_points[TYPE(I_ACHBRT)] = Point(QImage(":/marine/anchorage.png"));
|
_points[TYPE(ACHBRT)].setTextColor(QColor(0xeb, 0x49, 0xeb));
|
||||||
|
_points[TYPE(ACHBRT)].setHaloColor(QColor());
|
||||||
|
_points[TYPE(I_ACHBRT)] = _points[TYPE(ACHBRT)];
|
||||||
_points[TYPE(OFSPLF)] = Point(QImage(":/marine/platform.png"));
|
_points[TYPE(OFSPLF)] = Point(QImage(":/marine/platform.png"));
|
||||||
_points[TYPE(PILPNT)] = Point(QImage(":/marine/pile.png"), Small);
|
_points[TYPE(PILPNT)] = Point(QImage(":/marine/pile.png"), Small);
|
||||||
_points[SUBTYPE(MORFAC, 1)] = Point(QImage(":/marine/pile.png"), Small);
|
_points[SUBTYPE(MORFAC, 1)] = Point(QImage(":/marine/pile.png"), Small);
|
||||||
@ -366,6 +376,8 @@ void Style::pointStyle(qreal ratio)
|
|||||||
_points[SUBTYPE(WEDKLP, 0)] = Point(QImage(":/marine/kelp.png"));
|
_points[SUBTYPE(WEDKLP, 0)] = Point(QImage(":/marine/kelp.png"));
|
||||||
_points[SUBTYPE(WEDKLP, 1)] = Point(QImage(":/marine/kelp.png"));
|
_points[SUBTYPE(WEDKLP, 1)] = Point(QImage(":/marine/kelp.png"));
|
||||||
_points[TYPE(SEAARE)].setHaloColor(QColor());
|
_points[TYPE(SEAARE)].setHaloColor(QColor());
|
||||||
|
_points[TYPE(LNDARE)].setHaloColor(QColor());
|
||||||
|
_points[TYPE(LNDRGN)].setHaloColor(QColor());
|
||||||
_points[TYPE(RADRFL)] = Point(QImage(":/marine/radar-reflector.png"));
|
_points[TYPE(RADRFL)] = Point(QImage(":/marine/radar-reflector.png"));
|
||||||
|
|
||||||
_points[SUBTYPE(I_BERTHS, 6)] = Point(QImage(":/marine/fleeting-area.png"),
|
_points[SUBTYPE(I_BERTHS, 6)] = Point(QImage(":/marine/fleeting-area.png"),
|
||||||
@ -427,6 +439,9 @@ void Style::pointStyle(qreal ratio)
|
|||||||
Style::Style(qreal ratio)
|
Style::Style(qreal ratio)
|
||||||
{
|
{
|
||||||
_light = QImage(":/marine/light.png");
|
_light = QImage(":/marine/light.png");
|
||||||
|
_lightRed = QImage(":/marine/light-red.png");
|
||||||
|
_lightGreen = QImage(":/marine/light-green.png");
|
||||||
|
_lightYellow = QImage(":/marine/light-yellow.png");
|
||||||
_lightOffset = QPoint(11, 11);
|
_lightOffset = QPoint(11, 11);
|
||||||
_signal = QImage(":/marine/fog-signal.png");
|
_signal = QImage(":/marine/fog-signal.png");
|
||||||
_signalOffset = QPoint(-9, 9);
|
_signalOffset = QPoint(-9, 9);
|
||||||
@ -477,3 +492,37 @@ const QFont *Style::font(Style::FontSize size) const
|
|||||||
return &_normal;
|
return &_normal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const QImage *Style::light(Color color) const
|
||||||
|
{
|
||||||
|
switch (color) {
|
||||||
|
case Red:
|
||||||
|
return &_lightRed;
|
||||||
|
case Green:
|
||||||
|
return &_lightGreen;
|
||||||
|
case White:
|
||||||
|
case Yellow:
|
||||||
|
case Amber:
|
||||||
|
case Orange:
|
||||||
|
return &_lightYellow;
|
||||||
|
default:
|
||||||
|
return &_light;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QColor Style::color(Style::Color c)
|
||||||
|
{
|
||||||
|
switch (c) {
|
||||||
|
case Red:
|
||||||
|
return Qt::red;
|
||||||
|
case Green:
|
||||||
|
return Qt::green;
|
||||||
|
case White:
|
||||||
|
case Yellow:
|
||||||
|
case Amber:
|
||||||
|
case Orange:
|
||||||
|
return Qt::yellow;
|
||||||
|
default:
|
||||||
|
return Qt::magenta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -89,6 +89,11 @@ public:
|
|||||||
QPoint _offset;
|
QPoint _offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum Color {
|
||||||
|
Unknown, White, Black, Red, Green, Blue, Yellow, Gray,
|
||||||
|
Brown, Amber, Violet, Orange, Magenta, Pink
|
||||||
|
};
|
||||||
|
|
||||||
Style(qreal ratio);
|
Style(qreal ratio);
|
||||||
|
|
||||||
const Line &line(uint type) const;
|
const Line &line(uint type) const;
|
||||||
@ -97,11 +102,13 @@ public:
|
|||||||
const QVector<uint> &drawOrder() const {return _drawOrder;}
|
const QVector<uint> &drawOrder() const {return _drawOrder;}
|
||||||
|
|
||||||
const QFont *font(Style::FontSize size) const;
|
const QFont *font(Style::FontSize size) const;
|
||||||
const QImage *light() const {return &_light;}
|
const QImage *light(Color color) const;
|
||||||
const QImage *signal() const {return &_signal;}
|
const QImage *signal() const {return &_signal;}
|
||||||
const QPoint &lightOffset() const {return _lightOffset;}
|
const QPoint &lightOffset() const {return _lightOffset;}
|
||||||
const QPoint &signalOffset() const {return _signalOffset;}
|
const QPoint &signalOffset() const {return _signalOffset;}
|
||||||
|
|
||||||
|
static QColor color(Color c);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void polygonStyle();
|
void polygonStyle();
|
||||||
void lineStyle(qreal ratio);
|
void lineStyle(qreal ratio);
|
||||||
@ -114,7 +121,7 @@ private:
|
|||||||
|
|
||||||
/* Fonts and images must be initialized after QGuiApplication! */
|
/* Fonts and images must be initialized after QGuiApplication! */
|
||||||
QFont _small, _normal, _large;
|
QFont _small, _normal, _large;
|
||||||
QImage _light, _signal;
|
QImage _light, _lightRed, _lightGreen, _lightYellow, _signal;
|
||||||
QPoint _lightOffset, _signalOffset;
|
QPoint _lightOffset, _signalOffset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
51
src/map/IMG/lights.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#ifndef IMG_LIGHTS_H
|
||||||
|
#define IMG_LIGHTS_H
|
||||||
|
|
||||||
|
#include <QVector>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
namespace IMG {
|
||||||
|
|
||||||
|
class Lights
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum Color {None, Red, Green, White, Blue, Yellow, Violet, Amber};
|
||||||
|
|
||||||
|
struct Sector
|
||||||
|
{
|
||||||
|
Sector() : color(None), angle(0), range(0) {}
|
||||||
|
Sector(Color color, quint32 angle, quint32 range)
|
||||||
|
: color(color), angle(angle), range(range) {}
|
||||||
|
|
||||||
|
Color color;
|
||||||
|
quint32 angle;
|
||||||
|
quint32 range;
|
||||||
|
};
|
||||||
|
|
||||||
|
Lights() : color(None), range(0) {}
|
||||||
|
bool isSectorLight() const {return ((color && range) || !sectors.isEmpty());}
|
||||||
|
|
||||||
|
Color color;
|
||||||
|
quint32 range;
|
||||||
|
QVector<Sector> sectors;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef QT_NO_DEBUG
|
||||||
|
inline QDebug operator<<(QDebug dbg, const IMG::Lights::Sector §or)
|
||||||
|
{
|
||||||
|
dbg.nospace() << "Sector(" << sector.color << ", " << sector.angle
|
||||||
|
<< ", " << sector.range << ")";
|
||||||
|
return dbg.space();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline QDebug operator<<(QDebug dbg, const IMG::Lights &lights)
|
||||||
|
{
|
||||||
|
dbg.nospace() << "Lights(" << lights.color << ", " << lights.range << ", "
|
||||||
|
<< lights.sectors << ")";
|
||||||
|
return dbg.space();
|
||||||
|
}
|
||||||
|
#endif // QT_NO_DEBUG
|
||||||
|
|
||||||
|
#endif // IMG_LIGHTS_H
|
@ -14,6 +14,7 @@
|
|||||||
#include "map/matrix.h"
|
#include "map/matrix.h"
|
||||||
#include "label.h"
|
#include "label.h"
|
||||||
#include "raster.h"
|
#include "raster.h"
|
||||||
|
#include "lights.h"
|
||||||
#include "zoom.h"
|
#include "zoom.h"
|
||||||
|
|
||||||
namespace IMG {
|
namespace IMG {
|
||||||
@ -51,11 +52,11 @@ public:
|
|||||||
enum Flags {
|
enum Flags {
|
||||||
NoFlag = 0,
|
NoFlag = 0,
|
||||||
ClassLabel = 1,
|
ClassLabel = 1,
|
||||||
Light = 2
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Coordinates coordinates;
|
Coordinates coordinates;
|
||||||
Label label;
|
Label label;
|
||||||
|
Lights lights;
|
||||||
quint64 id;
|
quint64 id;
|
||||||
quint32 type;
|
quint32 type;
|
||||||
quint32 flags;
|
quint32 flags;
|
||||||
|
@ -18,13 +18,13 @@ using namespace IMG;
|
|||||||
|
|
||||||
#define TEXT_EXTENT 160
|
#define TEXT_EXTENT 160
|
||||||
#define ICON_PADDING 2
|
#define ICON_PADDING 2
|
||||||
|
#define RANGE_FACTOR 4
|
||||||
|
#define ROAD 0
|
||||||
|
#define WATER 1
|
||||||
|
|
||||||
#define AREA(rect) \
|
#define AREA(rect) \
|
||||||
(rect.size().width() * rect.size().height())
|
(rect.size().width() * rect.size().height())
|
||||||
|
|
||||||
#define ROAD 0
|
|
||||||
#define WATER 1
|
|
||||||
|
|
||||||
static const QColor textColor(Qt::black);
|
static const QColor textColor(Qt::black);
|
||||||
static const QColor haloColor(Qt::white);
|
static const QColor haloColor(Qt::white);
|
||||||
static const QColor shieldColor(Qt::white);
|
static const QColor shieldColor(Qt::white);
|
||||||
@ -226,6 +226,67 @@ void RasterTile::drawTextItems(QPainter *painter,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static QRect lightRect(const QPoint &pos, quint32 range)
|
||||||
|
{
|
||||||
|
return QRect(pos.x() - range * RANGE_FACTOR, pos.y() - range * RANGE_FACTOR,
|
||||||
|
2*range * RANGE_FACTOR, 2*range * RANGE_FACTOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RasterTile::drawSectorLights(QPainter *painter,
|
||||||
|
const QList<const MapData::Point *> &lights) const
|
||||||
|
{
|
||||||
|
for (int i = 0; i < lights.size(); i++) {
|
||||||
|
const MapData::Point *p = lights.at(i);
|
||||||
|
QPoint pos(p->coordinates.lon(), p->coordinates.lat());
|
||||||
|
|
||||||
|
if (p->lights.sectors.size()) {
|
||||||
|
for (int j = 0; j < p->lights.sectors.size(); j++) {
|
||||||
|
const Lights::Sector &start = p->lights.sectors.at(j);
|
||||||
|
const Lights::Sector &end = (j == p->lights.sectors.size() - 1)
|
||||||
|
? p->lights.sectors.at(0) : p->lights.sectors.at(j+1);
|
||||||
|
|
||||||
|
if (start.color) {
|
||||||
|
double a1 = -(end.angle / 10.0 + 90.0);
|
||||||
|
double a2 = -(start.angle / 10.0 + 90.0);
|
||||||
|
if (a1 > a2)
|
||||||
|
a2 += 360;
|
||||||
|
double as = (a2 - a1);
|
||||||
|
if (as == 0)
|
||||||
|
as = 360;
|
||||||
|
|
||||||
|
QRect rect(lightRect(pos, start.range ? start.range : 6));
|
||||||
|
|
||||||
|
painter->setPen(QPen(Qt::black, 6, Qt::SolidLine,
|
||||||
|
Qt::FlatCap));
|
||||||
|
painter->drawArc(rect, a1 * 16, as * 16);
|
||||||
|
painter->setPen(QPen(Style::color(start.color), 4,
|
||||||
|
Qt::SolidLine, Qt::FlatCap));
|
||||||
|
painter->drawArc(rect, a1 * 16, as * 16);
|
||||||
|
|
||||||
|
if (a2 - a1 != 0) {
|
||||||
|
QLineF ln(pos, QPointF(pos.x() + rect.width(), pos.y()));
|
||||||
|
ln.setAngle(a1);
|
||||||
|
painter->setPen(QPen(Qt::black, 1, Qt::DashLine));
|
||||||
|
painter->drawLine(ln);
|
||||||
|
ln.setAngle(a2);
|
||||||
|
painter->drawLine(ln);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (p->lights.color && p->lights.range) {
|
||||||
|
QRect rect(lightRect(pos, p->lights.range));
|
||||||
|
|
||||||
|
painter->setPen(QPen(Qt::black, 6, Qt::SolidLine, Qt::FlatCap));
|
||||||
|
painter->drawArc(rect, 0, 360 * 16);
|
||||||
|
painter->setPen(QPen(Style::color(p->lights.color), 4,
|
||||||
|
Qt::SolidLine, Qt::FlatCap));
|
||||||
|
painter->drawArc(rect, 0, 360 * 16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void removeDuplicitLabel(QList<TextItem *> &labels, const QString &text,
|
static void removeDuplicitLabel(QList<TextItem *> &labels, const QString &text,
|
||||||
const QRectF &tileRect)
|
const QRectF &tileRect)
|
||||||
{
|
{
|
||||||
@ -398,7 +459,7 @@ void RasterTile::processShields(const QList<MapData::Poly> &lines,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RasterTile::processPoints(QList<MapData::Point> &points,
|
void RasterTile::processPoints(QList<MapData::Point> &points,
|
||||||
QList<TextItem*> &textItems)
|
QList<TextItem*> &textItems, QList<const MapData::Point*> &lights)
|
||||||
{
|
{
|
||||||
std::sort(points.begin(), points.end());
|
std::sort(points.begin(), points.end());
|
||||||
|
|
||||||
@ -408,6 +469,9 @@ void RasterTile::processPoints(QList<MapData::Point> &points,
|
|||||||
const Style::Point &ps = style->point(point.type);
|
const Style::Point &ps = style->point(point.type);
|
||||||
bool poi = Style::isPOI(point.type);
|
bool poi = Style::isPOI(point.type);
|
||||||
|
|
||||||
|
if (point.lights.isSectorLight())
|
||||||
|
lights.append(&point);
|
||||||
|
|
||||||
const QString *label = point.label.text().isEmpty()
|
const QString *label = point.label.text().isEmpty()
|
||||||
? 0 : &(point.label.text());
|
? 0 : &(point.label.text());
|
||||||
const QImage *img = ps.img().isNull() ? 0 : &ps.img();
|
const QImage *img = ps.img().isNull() ? 0 : &ps.img();
|
||||||
@ -428,11 +492,12 @@ void RasterTile::processPoints(QList<MapData::Point> &points,
|
|||||||
|
|
||||||
TextPointItem *item = new TextPointItem(pos + offset, label, fnt, img,
|
TextPointItem *item = new TextPointItem(pos + offset, label, fnt, img,
|
||||||
color, hcolor, 0, ICON_PADDING);
|
color, hcolor, 0, ICON_PADDING);
|
||||||
if (item->isValid() && !item->collides(textItems)) {
|
if (item->isValid() && (point.lights.isSectorLight()
|
||||||
|
|| !item->collides(textItems))) {
|
||||||
textItems.append(item);
|
textItems.append(item);
|
||||||
if (Style::isLight(point.type) || point.flags & MapData::Point::Light)
|
if (point.lights.color && !point.lights.isSectorLight())
|
||||||
textItems.append(new TextPointItem(pos + style->lightOffset(),
|
textItems.append(new TextPointItem(pos + style->lightOffset(),
|
||||||
0, 0, style->light(), 0, 0, 0, 0));
|
0, 0, style->light(point.lights.color), 0, 0, 0, 0));
|
||||||
} else
|
} else
|
||||||
delete item;
|
delete item;
|
||||||
}
|
}
|
||||||
@ -521,6 +586,7 @@ void RasterTile::render()
|
|||||||
QList<MapData::Poly> lines;
|
QList<MapData::Poly> lines;
|
||||||
QList<MapData::Point> points;
|
QList<MapData::Point> points;
|
||||||
QList<TextItem*> textItems;
|
QList<TextItem*> textItems;
|
||||||
|
QList<const MapData::Point*> lights;
|
||||||
QImage arrows[2];
|
QImage arrows[2];
|
||||||
|
|
||||||
arrows[ROAD] = Util::svg2img(":/symbols/oneway.svg", _ratio);
|
arrows[ROAD] = Util::svg2img(":/symbols/oneway.svg", _ratio);
|
||||||
@ -531,7 +597,7 @@ void RasterTile::render()
|
|||||||
ll2xy(lines);
|
ll2xy(lines);
|
||||||
ll2xy(points);
|
ll2xy(points);
|
||||||
|
|
||||||
processPoints(points, textItems);
|
processPoints(points, textItems, lights);
|
||||||
processPolygons(polygons, textItems);
|
processPolygons(polygons, textItems);
|
||||||
processLines(lines, textItems, arrows);
|
processLines(lines, textItems, arrows);
|
||||||
|
|
||||||
@ -546,6 +612,7 @@ void RasterTile::render()
|
|||||||
drawPolygons(&painter, polygons);
|
drawPolygons(&painter, polygons);
|
||||||
drawHillShading(&painter);
|
drawHillShading(&painter);
|
||||||
drawLines(&painter, lines);
|
drawLines(&painter, lines);
|
||||||
|
drawSectorLights(&painter, lights);
|
||||||
drawTextItems(&painter, textItems);
|
drawTextItems(&painter, textItems);
|
||||||
|
|
||||||
qDeleteAll(textItems);
|
qDeleteAll(textItems);
|
||||||
|
@ -34,7 +34,8 @@ public:
|
|||||||
private:
|
private:
|
||||||
typedef RTree<const MapData::Elevation*, double, 2> DEMTRee;
|
typedef RTree<const MapData::Elevation*, double, 2> DEMTRee;
|
||||||
|
|
||||||
struct ElevationCTX {
|
struct ElevationCTX
|
||||||
|
{
|
||||||
ElevationCTX(const DEMTRee &tree, const Coordinates &c, double &ele)
|
ElevationCTX(const DEMTRee &tree, const Coordinates &c, double &ele)
|
||||||
: tree(tree), c(c), ele(ele) {}
|
: tree(tree), c(c), ele(ele) {}
|
||||||
|
|
||||||
@ -42,7 +43,8 @@ private:
|
|||||||
const Coordinates &c;
|
const Coordinates &c;
|
||||||
double &ele;
|
double &ele;
|
||||||
};
|
};
|
||||||
struct EdgeCTX {
|
struct EdgeCTX
|
||||||
|
{
|
||||||
EdgeCTX(const Coordinates &c, double &ele) : c(c), ele(ele) {}
|
EdgeCTX(const Coordinates &c, double &ele) : c(c), ele(ele) {}
|
||||||
|
|
||||||
const Coordinates &c;
|
const Coordinates &c;
|
||||||
@ -62,13 +64,14 @@ private:
|
|||||||
void drawLines(QPainter *painter, const QList<MapData::Poly> &lines) const;
|
void drawLines(QPainter *painter, const QList<MapData::Poly> &lines) const;
|
||||||
void drawTextItems(QPainter *painter, const QList<TextItem*> &textItems) const;
|
void drawTextItems(QPainter *painter, const QList<TextItem*> &textItems) const;
|
||||||
void drawHillShading(QPainter *painter) const;
|
void drawHillShading(QPainter *painter) const;
|
||||||
|
void drawSectorLights(QPainter *painter, const QList<const MapData::Point*> &lights) const;
|
||||||
|
|
||||||
void processPolygons(const QList<MapData::Poly> &polygons,
|
void processPolygons(const QList<MapData::Poly> &polygons,
|
||||||
QList<TextItem *> &textItems);
|
QList<TextItem *> &textItems);
|
||||||
void processLines(QList<MapData::Poly> &lines, QList<TextItem*> &textItems,
|
void processLines(QList<MapData::Poly> &lines, QList<TextItem*> &textItems,
|
||||||
const QImage (&arrows)[2]);
|
const QImage (&arrows)[2]);
|
||||||
void processPoints(QList<MapData::Point> &points,
|
void processPoints(QList<MapData::Point> &points, QList<TextItem*> &textItems,
|
||||||
QList<TextItem*> &textItems);
|
QList<const MapData::Point *> &lights);
|
||||||
void processShields(const QList<MapData::Poly> &lines,
|
void processShields(const QList<MapData::Poly> &lines,
|
||||||
QList<TextItem*> &textItems);
|
QList<TextItem*> &textItems);
|
||||||
void processStreetNames(const QList<MapData::Poly> &lines,
|
void processStreetNames(const QList<MapData::Poly> &lines,
|
||||||
|
@ -107,7 +107,8 @@ bool RGNFile::readObstructionInfo(Handle &hdl, quint8 flags, quint32 size,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RGNFile::readBuoyInfo(Handle &hdl, quint8 flags, MapData::Point *point) const
|
bool RGNFile::readBuoyInfo(Handle &hdl, quint8 flags, quint32 size,
|
||||||
|
MapData::Point *point) const
|
||||||
{
|
{
|
||||||
quint16 val;
|
quint16 val;
|
||||||
quint8 lc;
|
quint8 lc;
|
||||||
@ -115,7 +116,7 @@ bool RGNFile::readBuoyInfo(Handle &hdl, quint8 flags, MapData::Point *point) con
|
|||||||
if ((flags & 0xe0) != 0xe0)
|
if ((flags & 0xe0) != 0xe0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (!readUInt16(hdl, val))
|
if (!(size >= 2 && readUInt16(hdl, val)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
lc = (val >> 10) & 0x0f;
|
lc = (val >> 10) & 0x0f;
|
||||||
@ -123,7 +124,105 @@ bool RGNFile::readBuoyInfo(Handle &hdl, quint8 flags, MapData::Point *point) con
|
|||||||
lc = (val >> 6) & 7;
|
lc = (val >> 6) & 7;
|
||||||
|
|
||||||
if (lc)
|
if (lc)
|
||||||
point->flags |= MapData::Point::Light;
|
point->lights.color = (Lights::Color)lc;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RGNFile::readLightInfo(Handle &hdl, quint8 flags, quint32 size,
|
||||||
|
MapData::Point *point) const
|
||||||
|
{
|
||||||
|
quint16 flags1;
|
||||||
|
quint8 flags2;
|
||||||
|
quint32 unused;
|
||||||
|
|
||||||
|
if (!(size >= 3 && readUInt16(hdl, flags1) && readUInt8(hdl, flags2)))
|
||||||
|
return false;
|
||||||
|
size -= 3;
|
||||||
|
if (flags2 >> 6) {
|
||||||
|
if (!(size >= (flags2 >> 6) && readVUInt32(hdl, (flags2 >> 6), unused)))
|
||||||
|
return false;
|
||||||
|
size -= (flags2 >> 6);
|
||||||
|
}
|
||||||
|
if (flags2 >> 2 & 3) {
|
||||||
|
if (!(size >= (flags2 >> 2 & 3)
|
||||||
|
&& readVUInt32(hdl, (flags2 >> 2 & 3), unused)))
|
||||||
|
return false;
|
||||||
|
size -= (flags2 >> 2 & 3);
|
||||||
|
}
|
||||||
|
if (flags1 & 0xc0) {
|
||||||
|
if (flags1 & 0x80) {
|
||||||
|
if (!(size >= 1 && readUInt8(hdl, unused)))
|
||||||
|
return false;
|
||||||
|
unused |= ((flags1 & 0x40) << 2);
|
||||||
|
size--;
|
||||||
|
} else {
|
||||||
|
if (!(size >= 2 && readUInt16(hdl, unused)))
|
||||||
|
return false;
|
||||||
|
size -= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (flags & 2) {
|
||||||
|
if (!(size >= 3 && readUInt24(hdl, unused)))
|
||||||
|
return false;
|
||||||
|
size -= 3;
|
||||||
|
}
|
||||||
|
if (flags & 4) {
|
||||||
|
if (!(size >= 3 && readUInt24(hdl, unused)))
|
||||||
|
return false;
|
||||||
|
size -= 3;
|
||||||
|
}
|
||||||
|
if (flags & 8) {
|
||||||
|
if (!(size >= 3 && readUInt24(hdl, unused)))
|
||||||
|
return false;
|
||||||
|
size -= 3;
|
||||||
|
}
|
||||||
|
if (flags1 & 0x200) {
|
||||||
|
if (!(size >= 2 && readUInt16(hdl, unused)))
|
||||||
|
return false;
|
||||||
|
size -= 2;
|
||||||
|
}
|
||||||
|
if (flags1 & 0x400) {
|
||||||
|
if (!(size >= 1 && readUInt8(hdl, unused)))
|
||||||
|
return false;
|
||||||
|
size--;
|
||||||
|
}
|
||||||
|
if (flags1 & 0x800) {
|
||||||
|
quint16 la;
|
||||||
|
quint8 cf, range = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (!(size >= 2 && readUInt16(hdl, la)))
|
||||||
|
return false;
|
||||||
|
size -= 2;
|
||||||
|
|
||||||
|
cf = la >> 8;
|
||||||
|
Lights::Color c = (Lights::Color)(cf >> 4 & 7);
|
||||||
|
if (c) {
|
||||||
|
if (!(size >= 1 && readUInt8(hdl, range)))
|
||||||
|
return false;
|
||||||
|
size--;
|
||||||
|
}
|
||||||
|
point->lights.sectors.append(Lights::Sector(c, la & 0xfff, range));
|
||||||
|
} while (!(cf >> 7));
|
||||||
|
} else {
|
||||||
|
quint8 v1, v2, range;
|
||||||
|
|
||||||
|
if (!(size >= 1 && readUInt8(hdl, v1)))
|
||||||
|
return false;
|
||||||
|
size--;
|
||||||
|
|
||||||
|
range = v1 & 0x1f;
|
||||||
|
if ((v1 & 0x1f) == 0x1f) {
|
||||||
|
if (!(size >= 1 && readUInt8(hdl, v2)))
|
||||||
|
return false;
|
||||||
|
size--;
|
||||||
|
range += v2;
|
||||||
|
}
|
||||||
|
|
||||||
|
point->lights.color = (Lights::Color)(v1 >> 5);
|
||||||
|
point->lights.range = range;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -183,7 +282,9 @@ bool RGNFile::readClassFields(Handle &hdl, SegmentType segmentType,
|
|||||||
if (point && Style::isObstructionPoint(point->type))
|
if (point && Style::isObstructionPoint(point->type))
|
||||||
readObstructionInfo(hdl, flags, rs, point);
|
readObstructionInfo(hdl, flags, rs, point);
|
||||||
if (point && Style::isBuoy(point->type))
|
if (point && Style::isBuoy(point->type))
|
||||||
readBuoyInfo(hdl, flags, point);
|
readBuoyInfo(hdl, flags, rs, point);
|
||||||
|
if (point && Style::isLight(point->type))
|
||||||
|
readLightInfo(hdl, flags, rs, point);
|
||||||
|
|
||||||
return seek(hdl, off + rs);
|
return seek(hdl, off + rs);
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,10 @@ private:
|
|||||||
MapData::Point *point) const;
|
MapData::Point *point) const;
|
||||||
bool readObstructionInfo(Handle &hdl, quint8 flags, quint32 size,
|
bool readObstructionInfo(Handle &hdl, quint8 flags, quint32 size,
|
||||||
MapData::Point *point) const;
|
MapData::Point *point) const;
|
||||||
bool readBuoyInfo(Handle &hdl, quint8 flags, MapData::Point *point) const;
|
bool readBuoyInfo(Handle &hdl, quint8 flags, quint32 size,
|
||||||
|
MapData::Point *point) const;
|
||||||
|
bool readLightInfo(Handle &hdl, quint8 flags, quint32 size,
|
||||||
|
MapData::Point *point) const;
|
||||||
bool readLabel(Handle &hdl, LBLFile *lbl, Handle &lblHdl,
|
bool readLabel(Handle &hdl, LBLFile *lbl, Handle &lblHdl,
|
||||||
quint8 flags, quint32 size, MapData::Point *point) const;
|
quint8 flags, quint32 size, MapData::Point *point) const;
|
||||||
|
|
||||||
|
@ -1319,6 +1319,10 @@ Style::Style(qreal ratio, SubFile *typ)
|
|||||||
_extraSmall = pixelSizeFont(10);
|
_extraSmall = pixelSizeFont(10);
|
||||||
|
|
||||||
_light = QImage(":/marine/light.png");
|
_light = QImage(":/marine/light.png");
|
||||||
|
_lightRed = QImage(":/marine/light-red.png");
|
||||||
|
_lightGreen = QImage(":/marine/light-green.png");
|
||||||
|
_lightYellow = QImage(":/marine/light-yellow.png");
|
||||||
|
_lightWhite = QImage(":/marine/light-white.png");
|
||||||
_lightOffset = QPoint(11, 11);
|
_lightOffset = QPoint(11, 11);
|
||||||
|
|
||||||
defaultLineStyle(ratio);
|
defaultLineStyle(ratio);
|
||||||
@ -1373,6 +1377,40 @@ const QFont *Style::font(Style::FontSize size, Style::FontSize defaultSize) cons
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const QImage *Style::light(Lights::Color color) const
|
||||||
|
{
|
||||||
|
switch (color) {
|
||||||
|
case Lights::Red:
|
||||||
|
return &_lightRed;
|
||||||
|
case Lights::Green:
|
||||||
|
return &_lightGreen;
|
||||||
|
case Lights::White:
|
||||||
|
return &_lightWhite;
|
||||||
|
case Lights::Yellow:
|
||||||
|
case Lights::Amber:
|
||||||
|
return &_lightYellow;
|
||||||
|
default:
|
||||||
|
return &_light;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QColor Style::color(Lights::Color c)
|
||||||
|
{
|
||||||
|
switch (c) {
|
||||||
|
case Lights::Red:
|
||||||
|
return Qt::red;
|
||||||
|
case Lights::Green:
|
||||||
|
return Qt::green;
|
||||||
|
case Lights::White:
|
||||||
|
return Qt::white;
|
||||||
|
case Lights::Yellow:
|
||||||
|
case Lights::Amber:
|
||||||
|
return Qt::yellow;
|
||||||
|
default:
|
||||||
|
return Qt::magenta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef QT_NO_DEBUG
|
#ifndef QT_NO_DEBUG
|
||||||
static QString penColor(const QPen &pen)
|
static QString penColor(const QPen &pen)
|
||||||
{
|
{
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <QBrush>
|
#include <QBrush>
|
||||||
#include <QFont>
|
#include <QFont>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include "lights.h"
|
||||||
#include "subfile.h"
|
#include "subfile.h"
|
||||||
|
|
||||||
#define TYPE(t) ((t)<<8)
|
#define TYPE(t) ((t)<<8)
|
||||||
@ -112,8 +113,7 @@ public:
|
|||||||
const QList<quint32> &drawOrder() const {return _drawOrder;}
|
const QList<quint32> &drawOrder() const {return _drawOrder;}
|
||||||
const QFont *font(Style::FontSize size, Style::FontSize defaultSize
|
const QFont *font(Style::FontSize size, Style::FontSize defaultSize
|
||||||
= Style::Normal) const;
|
= Style::Normal) const;
|
||||||
|
const QImage *light(Lights::Color color) const;
|
||||||
const QImage *light() const {return &_light;}
|
|
||||||
const QPoint &lightOffset() const {return _lightOffset;}
|
const QPoint &lightOffset() const {return _lightOffset;}
|
||||||
|
|
||||||
static bool isPOI(quint32 type)
|
static bool isPOI(quint32 type)
|
||||||
@ -157,6 +157,8 @@ public:
|
|||||||
static bool isMarina(quint32 type)
|
static bool isMarina(quint32 type)
|
||||||
{return type == 0x10703;}
|
{return type == 0x10703;}
|
||||||
|
|
||||||
|
static QColor color(Lights::Color c);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Section {
|
struct Section {
|
||||||
quint32 offset;
|
quint32 offset;
|
||||||
@ -203,7 +205,7 @@ private:
|
|||||||
/* Fonts and images must be initialized after QGuiApplication! */
|
/* Fonts and images must be initialized after QGuiApplication! */
|
||||||
QFont _large, _normal, _small, _extraSmall;
|
QFont _large, _normal, _small, _extraSmall;
|
||||||
|
|
||||||
QImage _light;
|
QImage _light, _lightRed, _lightGreen, _lightYellow, _lightWhite;
|
||||||
QPoint _lightOffset;
|
QPoint _lightOffset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|