1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2025-05-14 15:17:32 +02:00

Render marine lines with the propper direction

This commit is contained in:
Martin Tůma 2025-05-10 14:27:51 +02:00
parent 535f4c0752
commit 4d33631844
8 changed files with 61 additions and 10 deletions

View File

@ -29,7 +29,12 @@ class MapData
{ {
public: public:
struct Poly { struct Poly {
Poly() : oneway(false) {} Poly() : flags(0) {}
enum Flags {
OneWay = 1,
Invert = 2
};
/* QPointF insted of Coordinates for performance reasons (no need to /* QPointF insted of Coordinates for performance reasons (no need to
duplicate all the vectors for drawing). Note, that we do not want to duplicate all the vectors for drawing). Note, that we do not want to
@ -40,7 +45,7 @@ public:
Raster raster; Raster raster;
quint32 type; quint32 type;
RectC boundingRect; RectC boundingRect;
bool oneway; quint32 flags;
bool operator<(const Poly &other) const bool operator<(const Poly &other) const
{return type > other.type;} {return type > other.type;}
@ -50,7 +55,6 @@ public:
Point() : id(0), flags(0) {} Point() : id(0), flags(0) {}
enum Flags { enum Flags {
NoFlag = 0,
ClassLabel = 1, ClassLabel = 1,
}; };

View File

@ -480,7 +480,7 @@ bool NETFile::link(const SubDiv *subdiv, quint32 shift, Handle &hdl,
if (lbl) if (lbl)
linkLabel(hdl, linkOffset, lbl, lblHdl, poly.label); linkLabel(hdl, linkOffset, lbl, lblHdl, poly.label);
if ((linkInfo.flags >> 3) & 1) if ((linkInfo.flags >> 3) & 1)
poly.oneway = true; poly.flags |= MapData::Poly::OneWay;
lines->append(poly); lines->append(poly);

View File

@ -206,9 +206,12 @@ void RasterTile::drawLines(QPainter *painter,
const MapData::Poly &poly = lines.at(i); const MapData::Poly &poly = lines.at(i);
const Style::Line &style = _data->style()->line(poly.type); const Style::Line &style = _data->style()->line(poly.type);
if (!style.img().isNull()) if (!style.img().isNull()) {
BitmapLine::draw(painter, poly.points, style.img()); if (poly.flags & MapData::Poly::Invert)
else if (style.foreground() != Qt::NoPen) { BitmapLine::drawr(painter, poly.points, style.img());
else
BitmapLine::draw(painter, poly.points, style.img());
} else if (style.foreground() != Qt::NoPen) {
painter->setPen(style.foreground()); painter->setPen(style.foreground());
painter->drawPolyline(poly.points); painter->drawPolyline(poly.points);
} }
@ -383,7 +386,7 @@ void RasterTile::processStreetNames(const QList<MapData::Poly> &lines,
? &style.text().color() : Style::isContourLine(poly.type) ? &style.text().color() : Style::isContourLine(poly.type)
? 0 : &textColor; ? 0 : &textColor;
const QColor *hColor = Style::isContourLine(poly.type) ? 0 : &haloColor; const QColor *hColor = Style::isContourLine(poly.type) ? 0 : &haloColor;
const QImage *img = poly.oneway const QImage *img = (poly.flags & MapData::Poly::OneWay)
? Style::isWaterLine(poly.type) ? Style::isWaterLine(poly.type)
? &arrows[WATER] : &arrows[ROAD] : 0; ? &arrows[WATER] : &arrows[ROAD] : 0;
const QString *label = poly.label.text().isEmpty() const QString *label = poly.label.text().isEmpty()

View File

@ -244,6 +244,22 @@ bool RGNFile::readLabel(Handle &hdl, LBLFile *lbl, Handle &lblHdl,
return true; return true;
} }
bool RGNFile::readLineInfo(Handle &hdl, quint32 size, MapData::Poly *line) const
{
if (size == 1) {
quint32 val;
if (!readUInt8(hdl, val))
return false;
if (((val >> 3) & 3) & 2)
line->flags |= MapData::Poly::Invert;
return true;
} else
return (!size);
}
bool RGNFile::readClassFields(Handle &hdl, SegmentType segmentType, bool RGNFile::readClassFields(Handle &hdl, SegmentType segmentType,
void *object, LBLFile *lbl, Handle &lblHdl) const void *object, LBLFile *lbl, Handle &lblHdl) const
{ {
@ -251,6 +267,8 @@ bool RGNFile::readClassFields(Handle &hdl, SegmentType segmentType,
quint32 rs = 0; quint32 rs = 0;
MapData::Poly *poly = (segmentType == Polygon) MapData::Poly *poly = (segmentType == Polygon)
? (MapData::Poly *) object : 0; ? (MapData::Poly *) object : 0;
MapData::Poly *line = (segmentType == Line)
? (MapData::Poly *) object : 0;
MapData::Point *point = (segmentType == Point) MapData::Point *point = (segmentType == Point)
? (MapData::Point *) object : 0; ? (MapData::Point *) object : 0;
@ -289,6 +307,9 @@ bool RGNFile::readClassFields(Handle &hdl, SegmentType segmentType,
if (point && Style::isLight(point->type)) if (point && Style::isLight(point->type))
readLightInfo(hdl, flags, rs, point); readLightInfo(hdl, flags, rs, point);
if (line && Style::isMarineLine(line->type))
readLineInfo(hdl, rs, line);
return seek(hdl, off + rs); return seek(hdl, off + rs);
} }
@ -597,8 +618,7 @@ bool RGNFile::polyObjects(Handle &hdl, const SubDiv *subdiv,
poly.type = (segmentType == Polygon) poly.type = (segmentType == Polygon)
? ((quint32)(type & 0x7F)) << 8 : ((quint32)(type & 0x3F)) << 8; ? ((quint32)(type & 0x7F)) << 8 : ((quint32)(type & 0x3F)) << 8;
if (segmentType == Line && type & 0x40) if (segmentType == Line && type & 0x40)
poly.oneway = true; poly.flags |= MapData::Poly::OneWay;
QPoint pos(subdiv->lon() + LS(lon, 24-subdiv->bits()), QPoint pos(subdiv->lon() + LS(lon, 24-subdiv->bits()),
subdiv->lat() + LS(lat, 24-subdiv->bits())); subdiv->lat() + LS(lat, 24-subdiv->bits()));

View File

@ -69,6 +69,7 @@ private:
MapData::Point *point) const; MapData::Point *point) const;
bool readLightInfo(Handle &hdl, quint8 flags, quint32 size, bool readLightInfo(Handle &hdl, quint8 flags, quint32 size,
MapData::Point *point) const; MapData::Point *point) const;
bool readLineInfo(Handle &hdl, quint32 size, MapData::Poly *line) 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;
bool readLclNavaid(Handle &hdl, quint32 size, bool readLclNavaid(Handle &hdl, quint32 size,

View File

@ -154,6 +154,8 @@ public:
{return (type >= 0x10100 && type < 0x10200);} {return (type >= 0x10100 && type < 0x10200);}
static bool isMarinePoint(quint32 type) static bool isMarinePoint(quint32 type)
{return type >= 0x10100 && type < 0x10a00;} {return type >= 0x10100 && type < 0x10a00;}
static bool isMarineLine(quint32 type)
{return type >= 0x10400 && type < 0x10700;}
static bool isMarina(quint32 type) static bool isMarina(quint32 type)
{return type == 0x10703;} {return type == 0x10703;}
static bool hasColorset(quint32 type) static bool hasColorset(quint32 type)

View File

@ -53,6 +53,26 @@ void BitmapLine::draw(QPainter *painter, const QPolygonF &line,
} }
} }
void BitmapLine::drawr(QPainter *painter, const QPolygonF &line,
const QImage &img)
{
int offset = 0;
for (int i = line.size() - 1; i > 0; i--) {
QLineF segment(line.at(i).x(), line.at(i).y(), line.at(i-1).x(),
line.at(i-1).y());
int len = qCeil(segment.length() * img.devicePixelRatio());
painter->save();
painter->translate(segment.p1());
painter->rotate(-segment.angle());
painter->drawImage(0.0, -img.height()/2.0, img2line(img, len, offset));
painter->restore();
offset = (len + offset) % img.width();
}
}
void BitmapLine::draw(QPainter *painter, const QVector<QPolygonF> &lines, void BitmapLine::draw(QPainter *painter, const QVector<QPolygonF> &lines,
const QImage &img) const QImage &img)
{ {

View File

@ -11,6 +11,7 @@ class QPainterPath;
namespace BitmapLine namespace BitmapLine
{ {
void draw(QPainter *painter, const QPolygonF &line, const QImage &img); void draw(QPainter *painter, const QPolygonF &line, const QImage &img);
void drawr(QPainter *painter, const QPolygonF &line, const QImage &img);
void draw(QPainter *painter, const QVector<QPolygonF> &lines, void draw(QPainter *painter, const QVector<QPolygonF> &lines,
const QImage &img); const QImage &img);
void draw(QPainter *painter, const QPainterPath &line, const QImage &img); void draw(QPainter *painter, const QPainterPath &line, const QImage &img);