1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2025-05-11 21:57:31 +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:
struct Poly {
Poly() : oneway(false) {}
Poly() : flags(0) {}
enum Flags {
OneWay = 1,
Invert = 2
};
/* QPointF insted of Coordinates for performance reasons (no need to
duplicate all the vectors for drawing). Note, that we do not want to
@ -40,7 +45,7 @@ public:
Raster raster;
quint32 type;
RectC boundingRect;
bool oneway;
quint32 flags;
bool operator<(const Poly &other) const
{return type > other.type;}
@ -50,7 +55,6 @@ public:
Point() : id(0), flags(0) {}
enum Flags {
NoFlag = 0,
ClassLabel = 1,
};

View File

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

View File

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

View File

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

View File

@ -69,6 +69,7 @@ private:
MapData::Point *point) const;
bool readLightInfo(Handle &hdl, quint8 flags, quint32 size,
MapData::Point *point) const;
bool readLineInfo(Handle &hdl, quint32 size, MapData::Poly *line) const;
bool readLabel(Handle &hdl, LBLFile *lbl, Handle &lblHdl,
quint8 flags, quint32 size, MapData::Point *point) const;
bool readLclNavaid(Handle &hdl, quint32 size,

View File

@ -154,6 +154,8 @@ public:
{return (type >= 0x10100 && type < 0x10200);}
static bool isMarinePoint(quint32 type)
{return type >= 0x10100 && type < 0x10a00;}
static bool isMarineLine(quint32 type)
{return type >= 0x10400 && type < 0x10700;}
static bool isMarina(quint32 type)
{return type == 0x10703;}
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,
const QImage &img)
{

View File

@ -11,6 +11,7 @@ class QPainterPath;
namespace BitmapLine
{
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,
const QImage &img);
void draw(QPainter *painter, const QPainterPath &line, const QImage &img);