1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-10-06 06:43:22 +02:00

Added support for line "dy" parameter

This commit is contained in:
Martin Tůma 2023-05-22 23:29:04 +02:00
parent ab7185bd25
commit 320b04c3fa
3 changed files with 64 additions and 2 deletions

View File

@ -1,3 +1,4 @@
#include <cmath>
#include <QPainter>
#include <QCache>
#include "common/programpaths.h"
@ -8,6 +9,8 @@ using namespace Mapsforge;
#define TEXT_EXTENT 160
static double limit = cos(deg2rad(170));
static qreal area(const QPainterPath &polygon)
{
qreal area = 0;
@ -55,6 +58,47 @@ static const QColor *haloColor(const Style::TextRender *ti)
? &ti->strokeColor() : 0;
}
static QPainterPath parallelPath(const QPainterPath &p, double dy)
{
int n = p.elementCount() - 1;
QVector<QPointF> u(n);
QPainterPath h;
#if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
h.reserve(p.elementCount());
#endif // QT 5.13
for (int k = 0; k < n; k++) {
qreal c = p.elementAt(k + 1).x - p.elementAt(k).x;
qreal s = p.elementAt(k + 1).y - p.elementAt(k).y;
qreal l = sqrt(c * c + s * s);
u[k] = (l == 0) ? QPointF(0, 0) : QPointF(c / l, s / l);
if (k == 0)
continue;
if (u.at(k).x() * u.at(k-1).x() + u.at(k).y() * u.at(k-1).y() < limit)
return p;
}
h.moveTo(QPointF(p.elementAt(0).x - dy * u.at(0).y(),
p.elementAt(0).y + dy * u.at(0).x()));
for (int k = 1; k < n; k++) {
qreal l = dy / (1 + u.at(k).x() * u.at(k-1).x()
+ u.at(k).y() * u.at(k-1).y());
QPainterPath::Element e(p.elementAt(k));
h.lineTo(QPointF(e.x - l * (u.at(k).y() + u.at(k-1).y()),
e.y + l * (u.at(k).x() + u.at(k-1).x())));
}
h.lineTo(QPointF(p.elementAt(n).x - dy * u.at(n-1).y(),
p.elementAt(n).y + dy * u.at(n-1).x()));
return h;
}
void RasterTile::processPointLabels(const QList<MapData::Point> &points,
QList<TextItem*> &textItems)
{
@ -306,13 +350,17 @@ void RasterTile::drawPaths(QPainter *painter, const QList<MapData::Path> &paths,
if (path) {
const Style::PathRender *ri = is.pathRender();
qreal dy = ri->dy(_zoom);
if (!path->pp.elementCount())
path->pp = painterPath(path->path->poly, ri->curve());
painter->setPen(ri->pen(_zoom));
painter->setBrush(ri->brush());
painter->drawPath(path->pp);
if (dy != 0)
painter->drawPath(parallelPath(path->pp, dy));
else
painter->drawPath(path->pp);
} else {
const Style::CircleRender *ri = is.circleRender();
qreal radius = ri->radius(_zoom);

View File

@ -245,6 +245,13 @@ void Style::line(QXmlStreamReader &reader, const Rule &rule)
if (curve == "cubic")
ri._curve = true;
}
if (attr.hasAttribute("dy")) {
ri._dy = attr.value("dy").toDouble(&ok);
if (!ok) {
reader.raiseError("invalid dy value");
return;
}
}
if (ri.rule()._type == Rule::AnyType || ri.rule()._type == Rule::WayType)
_paths.append(ri);
@ -689,6 +696,11 @@ QPen Style::PathRender::pen(int zoom) const
return Qt::NoPen;
}
qreal Style::PathRender::dy(int zoom) const
{
return (_scale && zoom >= 12) ? pow(1.5, zoom - 12) * _dy : _dy;
}
qreal Style::CircleRender::radius(int zoom) const
{
return (_scale && zoom >= 12) ? pow(1.5, zoom - 12) * _radius : _radius;

View File

@ -137,13 +137,14 @@ public:
PathRender(const Rule &rule, int zOrder) : Render(rule),
_zOrder(zOrder), _strokeWidth(0), _strokeCap(Qt::RoundCap),
_strokeJoin(Qt::RoundJoin), _area(false), _curve(false),
_scale(Stroke) {}
_scale(Stroke), _dy(0) {}
int zOrder() const {return _zOrder;}
QPen pen(int zoom) const;
const QBrush &brush() const {return _brush;}
bool area() const {return _area;}
bool curve() const {return _curve;}
qreal dy(int zoom) const;
private:
friend class Style;
@ -159,6 +160,7 @@ public:
QBrush _brush;
bool _area, _curve;
Scale _scale;
qreal _dy;
};
class CircleRender : public Render