From 0896b54831bcab5bab9220becfa2e530649b7b89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20T=C5=AFma?= Date: Wed, 19 Feb 2025 19:26:14 +0100 Subject: [PATCH 1/8] Improved marine lights presentation --- src/map/IMG/rastertile.cpp | 114 +++++++++++++++++++++++++++++-------- src/map/IMG/rastertile.h | 14 +++-- 2 files changed, 98 insertions(+), 30 deletions(-) diff --git a/src/map/IMG/rastertile.cpp b/src/map/IMG/rastertile.cpp index 236dfcbd..4e81c7d0 100644 --- a/src/map/IMG/rastertile.cpp +++ b/src/map/IMG/rastertile.cpp @@ -19,13 +19,37 @@ using namespace IMG; #define TEXT_EXTENT 160 #define ICON_PADDING 2 #define RANGE_FACTOR 4 -#define RANGE_MIN 6 #define ROAD 0 #define WATER 1 #define AREA(rect) \ (rect.size().width() * rect.size().height()) +struct Sector +{ + Sector(Light::Color color, quint32 start, quint32 end) + : color(color), start(start), end(end) {} + + bool operator==(const Sector &other) const + { + return (color == other.color && start == other.start && end == other.end); + } + bool operator<(const Sector &other) const + { + if (color == other.color) { + if (start == other.start) + return end < other.end; + else + return start < other.start; + } else + return color < other.color; + } + + Light::Color color; + quint32 start; + quint32 end; +}; + static const QColor textColor(Qt::black); static const QColor haloColor(Qt::white); static const QColor shieldColor(Qt::white); @@ -239,6 +263,7 @@ void RasterTile::drawSectorLights(QPainter *painter, for (int i = 0; i < lights.size(); i++) { const MapData::Point *p = lights.at(i); QPoint pos(p->coordinates.lon(), p->coordinates.lat()); + QMap rangeMap; for (int j = 0; j < p->lights.size(); j++) { const Light &l = p->lights.at(j); @@ -248,8 +273,16 @@ void RasterTile::drawSectorLights(QPainter *painter, const Light::Sector &start = l.sectors().at(k); const Light::Sector &end = (k == l.sectors().size() - 1) ? l.sectors().at(0) : l.sectors().at(k+1); + quint32 angle = end.angle() - start.angle(); + + if (start.color() && (angle || start.range())) { + quint32 range = start.range() ? start.range() : 6; + Sector s(start.color(), start.angle(), end.angle()); + if (rangeMap.value(s) >= range) + continue; + else + rangeMap.insert(s, range); - if (start.color()) { double a1 = -(end.angle() / 10.0 + 90.0); double a2 = -(start.angle() / 10.0 + 90.0); if (a1 > a2) @@ -258,9 +291,7 @@ void RasterTile::drawSectorLights(QPainter *painter, if (as == 0) as = 360; - QRect rect(lightRect(pos, start.range() - ? start.range() : RANGE_MIN)); - + QRect rect(lightRect(pos, range)); painter->setPen(QPen(Qt::black, 6, Qt::SolidLine, Qt::FlatCap)); painter->drawArc(rect, a1 * 16, as * 16); @@ -268,7 +299,7 @@ void RasterTile::drawSectorLights(QPainter *painter, Qt::SolidLine, Qt::FlatCap)); painter->drawArc(rect, a1 * 16, as * 16); - if (a2 - a1 != 0) { + if (angle) { QLineF ln(pos, QPointF(pos.x() + rect.width(), pos.y())); ln.setAngle(a1); @@ -279,9 +310,14 @@ void RasterTile::drawSectorLights(QPainter *painter, } } } - } else if (l.range() > RANGE_MIN) { - QRect rect(lightRect(pos, l.range())); + } else if (l.color() && l.range()) { + Sector s(l.color(), 0, 3600); + if (rangeMap.value(s) >= l.range()) + continue; + else + rangeMap.insert(s, l.range()); + QRect rect(lightRect(pos, l.range())); painter->setPen(QPen(Qt::black, 6, Qt::SolidLine, Qt::FlatCap)); painter->drawArc(rect, 0, 360 * 16); painter->setPen(QPen(Style::color(l.color()), 4, Qt::SolidLine, @@ -463,19 +499,47 @@ void RasterTile::processShields(const QList &lines, } } -static bool showAsSector(const QVector &lights) +static bool sectorLight(const QVector &lights) { for (int i = 0; i < lights.size(); i++) { const Light &l = lights.at(i); - if ((l.color() && l.range() > RANGE_MIN) || !l.sectors().isEmpty()) + if (l.color() && l.range()) return true; + for (int j = 0; j < l.sectors().size(); j++) { + const Light::Sector &start = l.sectors().at(j); + const Light::Sector &end = (j == l.sectors().size() - 1) + ? l.sectors().at(0) : l.sectors().at(j+1); + quint32 angle = end.angle() - start.angle(); + if (start.color() && (angle || start.range())) + return true; + } } return false; } +static Light::Color ordinaryLight(const QVector &lights) +{ + for (int i = 0; i < lights.size(); i++) { + const Light &l = lights.at(i); + if (l.color() && !l.range()) + return l.color(); + for (int j = 0; j < l.sectors().size(); j++) { + const Light::Sector &start = l.sectors().at(j); + const Light::Sector &end = (j == l.sectors().size() - 1) + ? l.sectors().at(0) : l.sectors().at(j+1); + quint32 angle = end.angle() - start.angle(); + if (start.color() && !angle && !start.range()) + return start.color(); + } + } + + return Light::None; +} + void RasterTile::processPoints(QList &points, - QList &textItems, QList &lights) + QList &textItems, QList &lights, + QList §orLights) { std::sort(points.begin(), points.end()); @@ -484,10 +548,10 @@ void RasterTile::processPoints(QList &points, const Style *style = _data->style(); const Style::Point &ps = style->point(point.type); bool poi = Style::isPOI(point.type); - bool sl = showAsSector(point.lights); + bool sl = sectorLight(point.lights); if (sl) - lights.append(&point); + sectorLights.append(&point); const QString *label = point.label.text().isEmpty() ? 0 : &(point.label.text()); @@ -511,17 +575,15 @@ void RasterTile::processPoints(QList &points, color, hcolor, 0, ICON_PADDING); if (item->isValid() && (sl || !item->collides(textItems))) { textItems.append(item); - for (int j = 0; j < point.lights.size(); j++) { - const Light &l = point.lights.at(j); - if (l.color() && l.range() <= RANGE_MIN) { - textItems.append(new TextPointItem(pos + style->lightOffset(), - 0, 0, style->light(l.color()), 0, 0, 0, 0)); - break; - } - } + Light::Color color = ordinaryLight(point.lights); + if (color) + lights.append(new TextPointItem(pos + style->lightOffset(), + 0, 0, style->light(color), 0, 0, 0, 0)); } else delete item; } + + } void RasterTile::fetchData(QList &polygons, @@ -606,8 +668,8 @@ void RasterTile::render() QList polygons; QList lines; QList points; - QList textItems; - QList lights; + QList textItems, lights; + QList sectorLights; QImage arrows[2]; arrows[ROAD] = Util::svg2img(":/symbols/oneway.svg", _ratio); @@ -618,7 +680,7 @@ void RasterTile::render() ll2xy(lines); ll2xy(points); - processPoints(points, textItems, lights); + processPoints(points, textItems, lights, sectorLights); processPolygons(polygons, textItems); processLines(lines, textItems, arrows); @@ -633,9 +695,11 @@ void RasterTile::render() drawPolygons(&painter, polygons); drawHillShading(&painter); drawLines(&painter, lines); - drawSectorLights(&painter, lights); + drawTextItems(&painter, lights); + drawSectorLights(&painter, sectorLights); drawTextItems(&painter, textItems); + qDeleteAll(lights); qDeleteAll(textItems); //painter.setPen(Qt::red); diff --git a/src/map/IMG/rastertile.h b/src/map/IMG/rastertile.h index 84c29052..9d7aaf96 100644 --- a/src/map/IMG/rastertile.h +++ b/src/map/IMG/rastertile.h @@ -60,18 +60,22 @@ private: void ll2xy(QList &polys) const; void ll2xy(QList &points) const; - void drawPolygons(QPainter *painter, const QList &polygons) const; + void drawPolygons(QPainter *painter, + const QList &polygons) const; void drawLines(QPainter *painter, const QList &lines) const; - void drawTextItems(QPainter *painter, const QList &textItems) const; + void drawTextItems(QPainter *painter, + const QList &textItems) const; void drawHillShading(QPainter *painter) const; - void drawSectorLights(QPainter *painter, const QList &lights) const; + void drawSectorLights(QPainter *painter, + const QList &lights) const; void processPolygons(const QList &polygons, QList &textItems); void processLines(QList &lines, QList &textItems, const QImage (&arrows)[2]); - void processPoints(QList &points, QList &textItems, - QList &lights); + void processPoints(QList &points, + QList &textItems, QList &lights, + QList §orLights); void processShields(const QList &lines, QList &textItems); void processStreetNames(const QList &lines, From cdf198ec1dbfd4dcde5a592a41f4881ae926b948 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20T=C5=AFma?= Date: Wed, 19 Feb 2025 22:48:12 +0100 Subject: [PATCH 2/8] Fixed clazy warning --- src/GUI/mapview.cpp | 2 +- src/GUI/mapview.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/GUI/mapview.cpp b/src/GUI/mapview.cpp index d139403c..86940503 100644 --- a/src/GUI/mapview.cpp +++ b/src/GUI/mapview.cpp @@ -1254,7 +1254,7 @@ void MapView::drawHillShading(bool draw) setMap(_map); } -void MapView::selectLayers(Layers layers) +void MapView::selectLayers(MapView::Layers layers) { _layers = layers; diff --git a/src/GUI/mapview.h b/src/GUI/mapview.h index 2bee70e3..4eaa467f 100644 --- a/src/GUI/mapview.h +++ b/src/GUI/mapview.h @@ -136,7 +136,7 @@ public slots: void showMotionInfo(bool show); void useStyles(bool use); void drawHillShading(bool draw); - void selectLayers(Layers layers); + void selectLayers(MapView::Layers layers); private slots: void updatePOI(); From 0cac0369aaf18ace19d5240f89a4f57b2e06fad4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20T=C5=AFma?= Date: Wed, 19 Feb 2025 22:49:19 +0100 Subject: [PATCH 3/8] Distinguish major/minor lights --- src/map/IMG/rastertile.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/map/IMG/rastertile.cpp b/src/map/IMG/rastertile.cpp index 4e81c7d0..12199142 100644 --- a/src/map/IMG/rastertile.cpp +++ b/src/map/IMG/rastertile.cpp @@ -19,6 +19,7 @@ using namespace IMG; #define TEXT_EXTENT 160 #define ICON_PADDING 2 #define RANGE_FACTOR 4 +#define MAJOR_RANGE 10 #define ROAD 0 #define WATER 1 @@ -275,7 +276,7 @@ void RasterTile::drawSectorLights(QPainter *painter, ? l.sectors().at(0) : l.sectors().at(k+1); quint32 angle = end.angle() - start.angle(); - if (start.color() && (angle || start.range())) { + if (start.color() && (angle || start.range() >= MAJOR_RANGE)) { quint32 range = start.range() ? start.range() : 6; Sector s(start.color(), start.angle(), end.angle()); if (rangeMap.value(s) >= range) @@ -310,7 +311,7 @@ void RasterTile::drawSectorLights(QPainter *painter, } } } - } else if (l.color() && l.range()) { + } else if (l.color() && l.range() >= MAJOR_RANGE) { Sector s(l.color(), 0, 3600); if (rangeMap.value(s) >= l.range()) continue; @@ -503,14 +504,14 @@ static bool sectorLight(const QVector &lights) { for (int i = 0; i < lights.size(); i++) { const Light &l = lights.at(i); - if (l.color() && l.range()) + if (l.color() && l.range() >= MAJOR_RANGE) return true; for (int j = 0; j < l.sectors().size(); j++) { const Light::Sector &start = l.sectors().at(j); const Light::Sector &end = (j == l.sectors().size() - 1) ? l.sectors().at(0) : l.sectors().at(j+1); quint32 angle = end.angle() - start.angle(); - if (start.color() && (angle || start.range())) + if (start.color() && (angle || start.range() >= MAJOR_RANGE)) return true; } } @@ -522,14 +523,14 @@ static Light::Color ordinaryLight(const QVector &lights) { for (int i = 0; i < lights.size(); i++) { const Light &l = lights.at(i); - if (l.color() && !l.range()) + if (l.color() && l.range() < MAJOR_RANGE) return l.color(); for (int j = 0; j < l.sectors().size(); j++) { const Light::Sector &start = l.sectors().at(j); const Light::Sector &end = (j == l.sectors().size() - 1) ? l.sectors().at(0) : l.sectors().at(j+1); quint32 angle = end.angle() - start.angle(); - if (start.color() && !angle && !start.range()) + if (start.color() && !angle && start.range() < MAJOR_RANGE) return start.color(); } } From b9fb9eece30a73705f5bd5945753d66326676387 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20T=C5=AFma?= Date: Wed, 19 Feb 2025 23:00:39 +0100 Subject: [PATCH 4/8] Use 10NM as the major/minor light threshold --- src/map/ENC/rastertile.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/map/ENC/rastertile.cpp b/src/map/ENC/rastertile.cpp index c0e57efb..d82e8019 100644 --- a/src/map/ENC/rastertile.cpp +++ b/src/map/ENC/rastertile.cpp @@ -14,6 +14,7 @@ using namespace ENC; #define TEXT_EXTENT 160 #define TSSLPT_SIZE 24 #define RANGE_FACTOR 4 +#define MAJOR_RANGE 10 static const float C1 = 0.866025f; /* sqrt(3)/2 */ static const QColor tsslptPen = QColor(0xeb, 0x49, 0xeb); @@ -277,7 +278,7 @@ void RasterTile::processPoints(QList &points, double range = attr.value(VALNMR).toDouble(); if (attr.contains(SECTR1) - || (range > 6 && !(point.type() & 0xFFFF))) { + || (range >= MAJOR_RANGE && !(point.type() & 0xFFFF))) { sectorLights.append(SectorLight(point.pos(), color, attr.value(LITVIS).toUInt(), range, attr.value(SECTR1).toDouble(), attr.value(SECTR2).toDouble())); From 48404ea43b82e5d82e0663689487ca90213566ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20T=C5=AFma?= Date: Thu, 20 Feb 2025 07:34:47 +0100 Subject: [PATCH 5/8] Limit the sector lights ranges --- src/map/ENC/rastertile.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/map/ENC/rastertile.cpp b/src/map/ENC/rastertile.cpp index d82e8019..2bc5668b 100644 --- a/src/map/ENC/rastertile.cpp +++ b/src/map/ENC/rastertile.cpp @@ -216,8 +216,8 @@ void RasterTile::drawTextItems(QPainter *painter, static QRectF lightRect(const QPointF &pos, double range) { - return QRectF(pos.x() - range * RANGE_FACTOR, pos.y() - range * RANGE_FACTOR, - 2*range * RANGE_FACTOR, 2*range * RANGE_FACTOR); + double r = qMin(range * RANGE_FACTOR, (double)TEXT_EXTENT); + return QRect(pos.x() - r, pos.y() - r, 2 * r, 2 * r); } void RasterTile::drawSectorLights(QPainter *painter, From ba49497608a7bda1c08448e151eaf31c7710662a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20T=C5=AFma?= Date: Thu, 20 Feb 2025 08:50:17 +0100 Subject: [PATCH 6/8] Code cleanup --- src/map/IMG/rastertile.cpp | 31 +++---------------------------- src/map/IMG/rastertile.h | 28 +++++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 29 deletions(-) diff --git a/src/map/IMG/rastertile.cpp b/src/map/IMG/rastertile.cpp index 12199142..aedf3fa1 100644 --- a/src/map/IMG/rastertile.cpp +++ b/src/map/IMG/rastertile.cpp @@ -26,31 +26,6 @@ using namespace IMG; #define AREA(rect) \ (rect.size().width() * rect.size().height()) -struct Sector -{ - Sector(Light::Color color, quint32 start, quint32 end) - : color(color), start(start), end(end) {} - - bool operator==(const Sector &other) const - { - return (color == other.color && start == other.start && end == other.end); - } - bool operator<(const Sector &other) const - { - if (color == other.color) { - if (start == other.start) - return end < other.end; - else - return start < other.start; - } else - return color < other.color; - } - - Light::Color color; - quint32 start; - quint32 end; -}; - static const QColor textColor(Qt::black); static const QColor haloColor(Qt::white); static const QColor shieldColor(Qt::white); @@ -259,7 +234,7 @@ static QRect lightRect(const QPoint &pos, quint32 range) } void RasterTile::drawSectorLights(QPainter *painter, - const QList &lights) const + const QList &lights) const { for (int i = 0; i < lights.size(); i++) { const MapData::Point *p = lights.at(i); @@ -329,7 +304,7 @@ void RasterTile::drawSectorLights(QPainter *painter, } } -static void removeDuplicitLabel(QList &labels, const QString &text, +static void removeDuplicitLabel(QList &labels, const QString &text, const QRectF &tileRect) { for (int i = 0; i < labels.size(); i++) { @@ -539,7 +514,7 @@ static Light::Color ordinaryLight(const QVector &lights) } void RasterTile::processPoints(QList &points, - QList &textItems, QList &lights, + QList &textItems, QList &lights, QList §orLights) { std::sort(points.begin(), points.end()); diff --git a/src/map/IMG/rastertile.h b/src/map/IMG/rastertile.h index 9d7aaf96..879656a2 100644 --- a/src/map/IMG/rastertile.h +++ b/src/map/IMG/rastertile.h @@ -51,6 +51,32 @@ private: double &ele; }; + struct Sector + { + Sector(Light::Color color, quint32 start, quint32 end) + : color(color), start(start), end(end) {} + + bool operator==(const Sector &other) const + { + return (color == other.color && start == other.start + && end == other.end); + } + bool operator<(const Sector &other) const + { + if (color == other.color) { + if (start == other.start) + return end < other.end; + else + return start < other.start; + } else + return color < other.color; + } + + Light::Color color; + quint32 start; + quint32 end; + }; + void fetchData(QList &polygons, QList &lines, QList &points); QPointF ll2xy(const Coordinates &c) const @@ -70,7 +96,7 @@ private: const QList &lights) const; void processPolygons(const QList &polygons, - QList &textItems); + QList &textItems); void processLines(QList &lines, QList &textItems, const QImage (&arrows)[2]); void processPoints(QList &points, From cc7209ad70aacaaeff9d81894a6d75a31d405d27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20T=C5=AFma?= Date: Thu, 20 Feb 2025 08:53:04 +0100 Subject: [PATCH 7/8] Removed obsolete stuff --- src/map/IMG/rastertile.h | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/src/map/IMG/rastertile.h b/src/map/IMG/rastertile.h index 879656a2..62afa9a9 100644 --- a/src/map/IMG/rastertile.h +++ b/src/map/IMG/rastertile.h @@ -32,25 +32,6 @@ public: void render(); private: - typedef RTree DEMTRee; - - struct ElevationCTX - { - ElevationCTX(const DEMTRee &tree, const Coordinates &c, double &ele) - : tree(tree), c(c), ele(ele) {} - - const DEMTRee &tree; - const Coordinates &c; - double &ele; - }; - struct EdgeCTX - { - EdgeCTX(const Coordinates &c, double &ele) : c(c), ele(ele) {} - - const Coordinates &c; - double &ele; - }; - struct Sector { Sector(Light::Color color, quint32 start, quint32 end) From 71a757983fc6779d36efb607d3715d49d4948937 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20T=C5=AFma?= Date: Thu, 20 Feb 2025 08:57:50 +0100 Subject: [PATCH 8/8] Some more obsolete stuff cleanup --- src/map/IMG/rastertile.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/map/IMG/rastertile.h b/src/map/IMG/rastertile.h index 62afa9a9..358d79b5 100644 --- a/src/map/IMG/rastertile.h +++ b/src/map/IMG/rastertile.h @@ -9,7 +9,6 @@ #include "style.h" class QPainter; -class IMGMap; class TextItem; namespace IMG {