mirror of
https://github.com/tumic0/GPXSee.git
synced 2024-11-30 22:51:16 +01:00
Properly match symbols to captions
This commit is contained in:
parent
5ddd63e697
commit
9afeaf672a
@ -106,40 +106,43 @@ void RasterTile::processPointLabels(const QList<MapData::Point> &points,
|
|||||||
{
|
{
|
||||||
QList<const Style::TextRender*> labels(_style->pointLabels(_zoom));
|
QList<const Style::TextRender*> labels(_style->pointLabels(_zoom));
|
||||||
QList<const Style::Symbol*> symbols(_style->pointSymbols(_zoom));
|
QList<const Style::Symbol*> symbols(_style->pointSymbols(_zoom));
|
||||||
QList<PainterPoint> painterPoints;
|
QList<PointText> items;
|
||||||
|
|
||||||
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);
|
||||||
const QByteArray *lbl = 0;
|
|
||||||
const Style::TextRender *ti = 0;
|
const Style::TextRender *ti = 0;
|
||||||
const Style::Symbol *si = 0;
|
const Style::Symbol *si = 0;
|
||||||
|
const QByteArray *lbl = 0;
|
||||||
|
|
||||||
|
for (int j = 0; j < symbols.size(); j++) {
|
||||||
|
const Style::Symbol *ri = symbols.at(j);
|
||||||
|
|
||||||
|
if (ri->rule().match(point.tags))
|
||||||
|
if (!si || si->priority() < ri->priority())
|
||||||
|
si = ri;
|
||||||
|
}
|
||||||
|
|
||||||
for (int j = 0; j < labels.size(); j++) {
|
for (int j = 0; j < labels.size(); j++) {
|
||||||
const Style::TextRender *ri = labels.at(j);
|
const Style::TextRender *ri = labels.at(j);
|
||||||
if (ri->rule().match(point.tags)) {
|
if (ri->rule().match(point.tags)) {
|
||||||
if ((lbl = label(ri->key(), point.tags))) {
|
if ((lbl = label(ri->key(), point.tags))) {
|
||||||
|
if (si && si->id() != ri->symbolId())
|
||||||
|
continue;
|
||||||
|
|
||||||
ti = ri;
|
ti = ri;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < symbols.size(); j++) {
|
|
||||||
const Style::Symbol *ri = symbols.at(j);
|
|
||||||
if (ri->rule().match(point.tags)) {
|
|
||||||
si = ri;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ti || si)
|
if (ti || si)
|
||||||
painterPoints.append(PainterPoint(&point, lbl, si, ti));
|
items.append(PointText(&point, lbl, si, ti));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::sort(painterPoints.begin(), painterPoints.end());
|
std::sort(items.begin(), items.end());
|
||||||
|
|
||||||
for (int i = 0; i < painterPoints.size(); i++) {
|
for (int i = 0; i < items.size(); i++) {
|
||||||
const PainterPoint &p = painterPoints.at(i);
|
const PointText &p = items.at(i);
|
||||||
const QImage *img = p.si ? &p.si->img() : 0;
|
const QImage *img = p.si ? &p.si->img() : 0;
|
||||||
const QFont *font = p.ti ? &p.ti->font() : 0;
|
const QFont *font = p.ti ? &p.ti->font() : 0;
|
||||||
const QColor *color = p.ti ? &p.ti->fillColor() : 0;
|
const QColor *color = p.ti ? &p.ti->fillColor() : 0;
|
||||||
@ -159,6 +162,7 @@ void RasterTile::processAreaLabels(const QVector<PainterPath> &paths,
|
|||||||
{
|
{
|
||||||
QList<const Style::TextRender*> labels(_style->areaLabels(_zoom));
|
QList<const Style::TextRender*> labels(_style->areaLabels(_zoom));
|
||||||
QList<const Style::Symbol*> symbols(_style->areaSymbols(_zoom));
|
QList<const Style::Symbol*> symbols(_style->areaSymbols(_zoom));
|
||||||
|
QList<PathText> items;
|
||||||
|
|
||||||
for (int i = 0; i < paths.size(); i++) {
|
for (int i = 0; i < paths.size(); i++) {
|
||||||
const PainterPath &path = paths.at(i);
|
const PainterPath &path = paths.at(i);
|
||||||
@ -169,34 +173,43 @@ void RasterTile::processAreaLabels(const QVector<PainterPath> &paths,
|
|||||||
if (!path.path->closed)
|
if (!path.path->closed)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
for (int j = 0; j < symbols.size(); j++) {
|
||||||
|
const Style::Symbol *ri = symbols.at(j);
|
||||||
|
|
||||||
|
if (ri->rule().match(path.path->closed, path.path->tags))
|
||||||
|
if (!si || si->priority() < ri->priority())
|
||||||
|
si = ri;
|
||||||
|
}
|
||||||
|
|
||||||
for (int j = 0; j < labels.size(); j++) {
|
for (int j = 0; j < labels.size(); j++) {
|
||||||
const Style::TextRender *ri = labels.at(j);
|
const Style::TextRender *ri = labels.at(j);
|
||||||
if (ri->rule().match(path.path->closed, path.path->tags)) {
|
if (ri->rule().match(path.path->closed, path.path->tags)) {
|
||||||
if ((lbl = label(ri->key(), path.path->tags)))
|
if ((lbl = label(ri->key(), path.path->tags))) {
|
||||||
|
if (si && si->id() != ri->symbolId())
|
||||||
|
continue;
|
||||||
|
|
||||||
ti = ri;
|
ti = ri;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < symbols.size(); j++) {
|
|
||||||
const Style::Symbol *ri = symbols.at(j);
|
|
||||||
if (ri->rule().match(path.path->tags)) {
|
|
||||||
si = ri;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ti && !si)
|
if (ti || si)
|
||||||
continue;
|
items.append(PathText(&path, lbl, si, ti));
|
||||||
|
}
|
||||||
|
|
||||||
const QImage *img = si ? &si->img() : 0;
|
std::sort(items.begin(), items.end());
|
||||||
const QFont *font = ti ? &ti->font() : 0;
|
|
||||||
const QColor *color = ti ? &ti->fillColor() : 0;
|
|
||||||
const QColor *hColor = ti ? haloColor(ti) : 0;
|
|
||||||
QPointF pos = path.path->labelPos.isNull()
|
|
||||||
? centroid(path.pp) : ll2xy(path.path->labelPos);
|
|
||||||
|
|
||||||
PointItem *item = new PointItem(pos.toPoint(), lbl, font, img, color,
|
for (int i = 0; i < items.size(); i++) {
|
||||||
|
const PathText &p = items.at(i);
|
||||||
|
const QImage *img = p.si ? &p.si->img() : 0;
|
||||||
|
const QFont *font = p.ti ? &p.ti->font() : 0;
|
||||||
|
const QColor *color = p.ti ? &p.ti->fillColor() : 0;
|
||||||
|
const QColor *hColor = p.ti ? haloColor(p.ti) : 0;
|
||||||
|
QPointF pos = p.p->path->labelPos.isNull()
|
||||||
|
? centroid(p.p->pp) : ll2xy(p.p->path->labelPos);
|
||||||
|
|
||||||
|
PointItem *item = new PointItem(pos.toPoint(), p.lbl, font, img, color,
|
||||||
hColor);
|
hColor);
|
||||||
if (item->isValid() && _rect.contains(item->boundingRect().toRect())
|
if (item->isValid() && _rect.contains(item->boundingRect().toRect())
|
||||||
&& !item->collides(textItems))
|
&& !item->collides(textItems))
|
||||||
@ -211,6 +224,7 @@ void RasterTile::processLineLabels(const QVector<PainterPath> &paths,
|
|||||||
{
|
{
|
||||||
QList<const Style::TextRender*> labels(_style->pathLabels(_zoom));
|
QList<const Style::TextRender*> labels(_style->pathLabels(_zoom));
|
||||||
QList<const Style::Symbol*> symbols(_style->lineSymbols(_zoom));
|
QList<const Style::Symbol*> symbols(_style->lineSymbols(_zoom));
|
||||||
|
QList<PathText> items;
|
||||||
QSet<QByteArray> set;
|
QSet<QByteArray> set;
|
||||||
|
|
||||||
for (int i = 0; i < paths.size(); i++) {
|
for (int i = 0; i < paths.size(); i++) {
|
||||||
@ -218,7 +232,6 @@ void RasterTile::processLineLabels(const QVector<PainterPath> &paths,
|
|||||||
const Style::TextRender *ti = 0;
|
const Style::TextRender *ti = 0;
|
||||||
const Style::Symbol *si = 0;
|
const Style::Symbol *si = 0;
|
||||||
const QByteArray *lbl = 0;
|
const QByteArray *lbl = 0;
|
||||||
bool limit = false;
|
|
||||||
|
|
||||||
if (path.path->closed)
|
if (path.path->closed)
|
||||||
continue;
|
continue;
|
||||||
@ -234,37 +247,44 @@ void RasterTile::processLineLabels(const QVector<PainterPath> &paths,
|
|||||||
|
|
||||||
for (int j = 0; j < symbols.size(); j++) {
|
for (int j = 0; j < symbols.size(); j++) {
|
||||||
const Style::Symbol *ri = symbols.at(j);
|
const Style::Symbol *ri = symbols.at(j);
|
||||||
if (ri->rule().match(path.path->tags)) {
|
if (ri->rule().match(path.path->closed, path.path->tags)) {
|
||||||
si = ri;
|
si = ri;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ti && !si)
|
if (ti || si)
|
||||||
continue;
|
items.append(PathText(&path, lbl, si, ti));
|
||||||
if (ti) {
|
}
|
||||||
limit = (ti->key() == ID_ELE || ti->key() == ID_REF);
|
|
||||||
if (limit && set.contains(*lbl))
|
std::sort(items.begin(), items.end());
|
||||||
|
|
||||||
|
for (int i = 0; i < items.size(); i++) {
|
||||||
|
const PathText &p = items.at(i);
|
||||||
|
const QImage *img = p.si ? &p.si->img() : 0;
|
||||||
|
const QFont *font = p.ti ? &p.ti->font() : 0;
|
||||||
|
const QColor *color = p.ti ? &p.ti->fillColor() : 0;
|
||||||
|
const QColor *hColor = p.ti ? haloColor(p.ti) : 0;
|
||||||
|
bool rotate = p.si ? p.si->rotate() : false;
|
||||||
|
bool limit = false;
|
||||||
|
|
||||||
|
if (p.ti) {
|
||||||
|
limit = (p.ti->key() == ID_ELE || p.ti->key() == ID_REF);
|
||||||
|
if (limit && set.contains(*p.lbl))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QImage *img = si ? &si->img() : 0;
|
PathItem *item = new PathItem(p.p->pp, p.lbl, img, _rect, font, color,
|
||||||
const QFont *font = ti ? &ti->font() : 0;
|
|
||||||
const QColor *color = ti ? &ti->fillColor() : 0;
|
|
||||||
const QColor *hColor = ti ? haloColor(ti) : 0;
|
|
||||||
bool rotate = si ? si->rotate() : false;
|
|
||||||
|
|
||||||
PathItem *item = new PathItem(path.pp, lbl, img, _rect, font, color,
|
|
||||||
hColor, rotate);
|
hColor, rotate);
|
||||||
if (item->isValid() && !item->collides(textItems)) {
|
if (item->isValid() && !item->collides(textItems)) {
|
||||||
textItems.append(item);
|
textItems.append(item);
|
||||||
if (limit)
|
if (limit)
|
||||||
set.insert(*lbl);
|
set.insert(*p.lbl);
|
||||||
} else {
|
} else {
|
||||||
delete item;
|
delete item;
|
||||||
|
|
||||||
if (img && lbl) {
|
if (img && p.lbl) {
|
||||||
PathItem *item = new PathItem(path.pp, 0, img, _rect, 0, 0, 0,
|
PathItem *item = new PathItem(p.p->pp, 0, img, _rect, 0, 0, 0,
|
||||||
rotate);
|
rotate);
|
||||||
if (item->isValid() && !item->collides(textItems))
|
if (item->isValid() && !item->collides(textItems))
|
||||||
textItems.append(item);
|
textItems.append(item);
|
||||||
|
@ -35,15 +35,15 @@ private:
|
|||||||
const MapData::Path *path;
|
const MapData::Path *path;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PainterPoint {
|
struct PointText {
|
||||||
PainterPoint(const MapData::Point *p, const QByteArray *lbl,
|
PointText(const MapData::Point *p, const QByteArray *lbl,
|
||||||
const Style::Symbol *si, const Style::TextRender *ti)
|
const Style::Symbol *si, const Style::TextRender *ti)
|
||||||
: p(p), lbl(lbl), ti(ti), si(si)
|
: p(p), lbl(lbl), ti(ti), si(si)
|
||||||
{
|
{
|
||||||
Q_ASSERT(si || ti);
|
Q_ASSERT(si || ti);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator<(const PainterPoint &other) const
|
bool operator<(const PointText &other) const
|
||||||
{
|
{
|
||||||
if (priority() == other.priority())
|
if (priority() == other.priority())
|
||||||
return p->id < other.p->id;
|
return p->id < other.p->id;
|
||||||
@ -58,6 +58,26 @@ private:
|
|||||||
const Style::Symbol *si;
|
const Style::Symbol *si;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct PathText {
|
||||||
|
PathText(const PainterPath *p, const QByteArray *lbl,
|
||||||
|
const Style::Symbol *si, const Style::TextRender *ti)
|
||||||
|
: p(p), lbl(lbl), ti(ti), si(si)
|
||||||
|
{
|
||||||
|
Q_ASSERT(si || ti);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator<(const PathText &other) const
|
||||||
|
{
|
||||||
|
return (priority() > other.priority());
|
||||||
|
}
|
||||||
|
int priority() const {return si ? si->priority() : ti->priority();}
|
||||||
|
|
||||||
|
const PainterPath *p;
|
||||||
|
const QByteArray *lbl;
|
||||||
|
const Style::TextRender *ti;
|
||||||
|
const Style::Symbol *si;
|
||||||
|
};
|
||||||
|
|
||||||
class RenderInstruction
|
class RenderInstruction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -421,6 +421,8 @@ void Style::text(QXmlStreamReader &reader, const MapData &data, const Rule &rule
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (attr.hasAttribute("symbol-id"))
|
||||||
|
ri._symbolId = attr.value("symbol-id").toString();
|
||||||
|
|
||||||
ri._font.setFamily(fontFamily);
|
ri._font.setFamily(fontFamily);
|
||||||
ri._font.setPixelSize(fontSize);
|
ri._font.setPixelSize(fontSize);
|
||||||
@ -482,6 +484,8 @@ void Style::symbol(QXmlStreamReader &reader, const QString &dir, qreal ratio,
|
|||||||
if (attr.value("rotate").toString() == "false")
|
if (attr.value("rotate").toString() == "false")
|
||||||
ri._rotate = false;
|
ri._rotate = false;
|
||||||
}
|
}
|
||||||
|
if (attr.hasAttribute("id"))
|
||||||
|
ri._id = attr.value("id").toString();
|
||||||
|
|
||||||
ri._img = image(file, width, height, percent, ratio);
|
ri._img = image(file, width, height, percent, ratio);
|
||||||
|
|
||||||
|
@ -192,6 +192,7 @@ public:
|
|||||||
: Render(rule), _priority(0), _fillColor(Qt::black),
|
: Render(rule), _priority(0), _fillColor(Qt::black),
|
||||||
_strokeColor(Qt::black), _strokeWidth(0) {}
|
_strokeColor(Qt::black), _strokeWidth(0) {}
|
||||||
|
|
||||||
|
const QString &symbolId() const {return _symbolId;}
|
||||||
const QFont &font() const {return _font;}
|
const QFont &font() const {return _font;}
|
||||||
const QColor &fillColor() const {return _fillColor;}
|
const QColor &fillColor() const {return _fillColor;}
|
||||||
const QColor &strokeColor() const {return _strokeColor;}
|
const QColor &strokeColor() const {return _strokeColor;}
|
||||||
@ -202,6 +203,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
friend class Style;
|
friend class Style;
|
||||||
|
|
||||||
|
QString _symbolId;
|
||||||
int _priority;
|
int _priority;
|
||||||
QColor _fillColor, _strokeColor;
|
QColor _fillColor, _strokeColor;
|
||||||
qreal _strokeWidth;
|
qreal _strokeWidth;
|
||||||
@ -212,15 +214,18 @@ public:
|
|||||||
class Symbol : public Render
|
class Symbol : public Render
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Symbol(const Rule &rule) : Render(rule), _priority(0), _rotate(true) {}
|
Symbol(const Rule &rule)
|
||||||
|
: Render(rule), _priority(0), _rotate(true) {}
|
||||||
|
|
||||||
|
const QString &id() const {return _id;}
|
||||||
const QImage &img() const {return _img;}
|
const QImage &img() const {return _img;}
|
||||||
int priority() const {return _priority;}
|
|
||||||
bool rotate() const {return _rotate;}
|
bool rotate() const {return _rotate;}
|
||||||
|
int priority() const {return _priority;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class Style;
|
friend class Style;
|
||||||
|
|
||||||
|
QString _id;
|
||||||
int _priority;
|
int _priority;
|
||||||
bool _rotate;
|
bool _rotate;
|
||||||
QImage _img;
|
QImage _img;
|
||||||
|
@ -382,5 +382,6 @@ void TextPathItem::paint(QPainter *painter) const
|
|||||||
|
|
||||||
//painter->setBrush(Qt::NoBrush);
|
//painter->setBrush(Qt::NoBrush);
|
||||||
//painter->setPen(Qt::red);
|
//painter->setPen(Qt::red);
|
||||||
|
//painter->setRenderHint(QPainter::Antialiasing, false);
|
||||||
//painter->drawPath(_shape);
|
//painter->drawPath(_shape);
|
||||||
}
|
}
|
||||||
|
@ -109,6 +109,7 @@ void TextPointItem::paint(QPainter *painter) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
//painter->setPen(Qt::red);
|
//painter->setPen(Qt::red);
|
||||||
|
//painter.setBrush(Qt::NoBrush);
|
||||||
//painter->setRenderHint(QPainter::Antialiasing, false);
|
//painter->setRenderHint(QPainter::Antialiasing, false);
|
||||||
//painter->drawRect(_rect);
|
//painter->drawRect(_rect);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user