mirror of
https://github.com/tumic0/GPXSee.git
synced 2025-01-18 19:52:09 +01:00
Layer rendering issue fix + optimization
This commit is contained in:
parent
f97f33f111
commit
ce6f03de73
@ -47,6 +47,8 @@ static QPointF centroid(const QPainterPath &polygon)
|
||||
void RasterTile::processPoints(QList<TextItem*> &textItems)
|
||||
{
|
||||
const Style &s = style();
|
||||
QList<const Style::TextRender*> labels(s.pointLabels(_zoom));
|
||||
QList<const Style::Symbol*> symbols(s.symbols(_zoom));
|
||||
|
||||
for (int i = 0; i < _points.size(); i++) {
|
||||
const MapData::Point &point = _points.at(i);
|
||||
@ -55,19 +57,19 @@ void RasterTile::processPoints(QList<TextItem*> &textItems)
|
||||
const Style::Symbol *si = 0;
|
||||
|
||||
if (label) {
|
||||
for (int i = 0; i < s.pointLabels().size(); i++) {
|
||||
const Style::TextRender &ri = s.pointLabels().at(i);
|
||||
if (ri.rule().match(_zoom, point.tags)) {
|
||||
ti = &ri;
|
||||
for (int i = 0; i < labels.size(); i++) {
|
||||
const Style::TextRender *ri = labels.at(i);
|
||||
if (ri->rule().match(point.tags)) {
|
||||
ti = ri;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < s.symbols().size(); i++) {
|
||||
const Style::Symbol &ri = s.symbols().at(i);
|
||||
if (ri.rule().match(_zoom, point.tags)) {
|
||||
si = &ri;
|
||||
for (int i = 0; i < symbols.size(); i++) {
|
||||
const Style::Symbol *ri = symbols.at(i);
|
||||
if (ri->rule().match(point.tags)) {
|
||||
si = ri;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -89,32 +91,33 @@ void RasterTile::processPoints(QList<TextItem*> &textItems)
|
||||
}
|
||||
}
|
||||
|
||||
void RasterTile::processPolygonNames(const QRect &tileRect,
|
||||
void RasterTile::processAreaNames(const QRect &tileRect,
|
||||
QList<TextItem*> &textItems)
|
||||
{
|
||||
const Style &s = style();
|
||||
QList<const Style::TextRender*> instructions(s.areaLabels(_zoom));
|
||||
QSet<QString> set;
|
||||
|
||||
for (int i = 0; i < s.pointLabels().size(); i++) {
|
||||
const Style::TextRender &ri = s.pointLabels().at(i);
|
||||
for (int i = 0; i < instructions.size(); i++) {
|
||||
const Style::TextRender *ri = instructions.at(i);
|
||||
|
||||
for (int j = 0; j < _paths.size(); j++) {
|
||||
const MapData::Path &path = _paths.at(j);
|
||||
|
||||
if (path.label.isEmpty())
|
||||
if (!path.closed || path.label.isEmpty())
|
||||
continue;
|
||||
if (!path.path.elementCount())
|
||||
continue;
|
||||
if (set.contains(path.label))
|
||||
continue;
|
||||
if (!ri.rule().match(_zoom, path.closed, path.tags))
|
||||
if (!ri->rule().match(path.closed, path.tags))
|
||||
continue;
|
||||
|
||||
QPointF pos = path.labelPos.isNull()
|
||||
? centroid(path.path) : ll2xy(path.labelPos);
|
||||
|
||||
TextPointItem *item = new TextPointItem(pos.toPoint(), &path.label,
|
||||
&ri.font(), 0, &ri.fillColor(), 0, false);
|
||||
&ri->font(), 0, &ri->fillColor(), 0, false);
|
||||
if (item->isValid() && tileRect.contains(item->boundingRect().toRect())
|
||||
&& !item->collides(textItems)) {
|
||||
textItems.append(item);
|
||||
@ -129,9 +132,10 @@ void RasterTile::processStreetNames(const QRect &tileRect,
|
||||
QList<TextItem*> &textItems)
|
||||
{
|
||||
const Style &s = style();
|
||||
QList<const Style::TextRender*> instructions(s.pathLabels(_zoom));
|
||||
|
||||
for (int i = 0; i < s.pathLabels().size(); i++) {
|
||||
const Style::TextRender &ri = s.pathLabels().at(i);
|
||||
for (int i = 0; i < instructions.size(); i++) {
|
||||
const Style::TextRender *ri = instructions.at(i);
|
||||
|
||||
for (int j = 0; j < _paths.size(); j++) {
|
||||
MapData::Path &path = _paths[j];
|
||||
@ -140,12 +144,12 @@ void RasterTile::processStreetNames(const QRect &tileRect,
|
||||
continue;
|
||||
if (!path.path.elementCount())
|
||||
continue;
|
||||
if (!ri.rule().match(_zoom, path.closed, path.tags))
|
||||
if (!ri->rule().match(path.closed, path.tags))
|
||||
continue;
|
||||
|
||||
TextPathItem *item = new TextPathItem(path.path,
|
||||
&path.label, tileRect, &ri.font(), &ri.fillColor(),
|
||||
&ri.strokeColor());
|
||||
&path.label, tileRect, &ri->font(), &ri->fillColor(),
|
||||
&ri->strokeColor());
|
||||
if (item->isValid() && !item->collides(textItems))
|
||||
textItems.append(item);
|
||||
else
|
||||
@ -208,19 +212,35 @@ QVector<RasterTile::PathInstruction> RasterTile::pathInstructions()
|
||||
void RasterTile::drawPaths(QPainter *painter)
|
||||
{
|
||||
QVector<PathInstruction> instructions(pathInstructions());
|
||||
const Style::PathRender *lri = 0;
|
||||
|
||||
QPixmap layer(_pixmap.size());
|
||||
layer.fill(Qt::transparent);
|
||||
|
||||
QPainter lp(&layer);
|
||||
lp.setRenderHint(QPainter::Antialiasing);
|
||||
lp.translate(-_xy.x(), -_xy.y());
|
||||
lp.setCompositionMode(QPainter::CompositionMode_Source);
|
||||
|
||||
for (int i = 0; i < instructions.size(); i++) {
|
||||
PathInstruction &is = instructions[i];
|
||||
const Style::PathRender *ri = is.render();
|
||||
|
||||
painter->setPen(ri->pen(_zoom));
|
||||
painter->setBrush(ri->brush());
|
||||
if (lri && ri != lri) {
|
||||
painter->drawPixmap(_xy, layer);
|
||||
layer.fill(Qt::transparent);
|
||||
}
|
||||
lri = ri;
|
||||
|
||||
if (!is.path()->path.elementCount())
|
||||
is.path()->path = painterPath(is.path()->poly);
|
||||
|
||||
painter->drawPath(is.path()->path);
|
||||
lp.setPen(ri->pen(_zoom));
|
||||
lp.setBrush(ri->brush());
|
||||
lp.drawPath(is.path()->path);
|
||||
}
|
||||
|
||||
painter->drawPixmap(_xy, layer);
|
||||
}
|
||||
|
||||
void RasterTile::render()
|
||||
@ -239,13 +259,13 @@ void RasterTile::render()
|
||||
drawPaths(&painter);
|
||||
|
||||
processPoints(textItems);
|
||||
processPolygonNames(tileRect, textItems);
|
||||
processAreaNames(tileRect, textItems);
|
||||
processStreetNames(tileRect, textItems);
|
||||
drawTextItems(&painter, textItems);
|
||||
|
||||
//painter.setPen(Qt::red);
|
||||
//painter.setBrush(Qt::NoBrush);
|
||||
//painter.drawRect(QRect(_xy, _img.size()));
|
||||
//painter.drawRect(QRect(_xy, _pixmap.size()));
|
||||
|
||||
qDeleteAll(textItems);
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ private:
|
||||
QPointF ll2xy(const Coordinates &c) const
|
||||
{return _transform.proj2img(_proj.ll2xy(c));}
|
||||
void processPoints(QList<TextItem*> &textItems);
|
||||
void processPolygonNames(const QRect &tileRect, QList<TextItem*> &textItems);
|
||||
void processAreaNames(const QRect &tileRect, QList<TextItem*> &textItems);
|
||||
void processStreetNames(const QRect &tileRect, QList<TextItem*> &textItems);
|
||||
QPainterPath painterPath(const Polygon &polygon) const;
|
||||
void drawTextItems(QPainter *painter, const QList<TextItem*> &textItems);
|
||||
|
@ -35,15 +35,19 @@ static QImage image(const QString &path, int width, int height)
|
||||
return QImage(path);
|
||||
}
|
||||
|
||||
bool Style::Rule::match(int zoom, bool closed,
|
||||
const QVector<MapData::Tag> &tags) const
|
||||
bool Style::Rule::match(const QVector<MapData::Tag> &tags) const
|
||||
{
|
||||
for (int i = 0; i < _filters.size(); i++)
|
||||
if (!_filters.at(i).match(tags))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Style::Rule::match(bool closed, const QVector<MapData::Tag> &tags) const
|
||||
{
|
||||
Closed cl = closed ? YesClosed : NoClosed;
|
||||
|
||||
if (_type && WayType != _type)
|
||||
return false;
|
||||
if (!_zooms.contains(zoom))
|
||||
return false;
|
||||
if (_closed && cl != _closed)
|
||||
return false;
|
||||
|
||||
@ -54,12 +58,17 @@ bool Style::Rule::match(int zoom, bool closed,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Style::Rule::match(int zoom, const QVector<MapData::Tag> &tags) const
|
||||
bool Style::Rule::match(int zoom, bool closed,
|
||||
const QVector<MapData::Tag> &tags) const
|
||||
{
|
||||
if (_type && NodeType != _type)
|
||||
Closed cl = closed ? YesClosed : NoClosed;
|
||||
|
||||
if (_type && WayType != _type)
|
||||
return false;
|
||||
if (!_zooms.contains(zoom))
|
||||
return false;
|
||||
if (_closed && cl != _closed)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < _filters.size(); i++)
|
||||
if (!_filters.at(i).match(tags))
|
||||
@ -136,7 +145,7 @@ void Style::line(QXmlStreamReader &reader, const Rule &rule)
|
||||
}
|
||||
|
||||
void Style::text(QXmlStreamReader &reader, const Rule &rule,
|
||||
QList<TextRender> &list)
|
||||
QList<QList<TextRender>*> &lists)
|
||||
{
|
||||
TextRender ri(rule);
|
||||
const QXmlStreamAttributes &attr = reader.attributes();
|
||||
@ -165,7 +174,8 @@ void Style::text(QXmlStreamReader &reader, const Rule &rule,
|
||||
ri._font.setBold(bold);
|
||||
ri._font.setItalic(italic);
|
||||
|
||||
list.append(ri);
|
||||
for (int i = 0; i < lists.size(); i++)
|
||||
lists[i]->append(ri);
|
||||
|
||||
reader.skipCurrentElement();
|
||||
}
|
||||
@ -233,10 +243,18 @@ void Style::rule(QXmlStreamReader &reader, const QString &dir,
|
||||
area(reader, dir, r);
|
||||
else if (reader.name() == QLatin1String("line"))
|
||||
line(reader, r);
|
||||
else if (reader.name() == QLatin1String("pathText"))
|
||||
text(reader, r, _pathLabels);
|
||||
else if (reader.name() == QLatin1String("caption"))
|
||||
text(reader, r, _pointLabels);
|
||||
else if (reader.name() == QLatin1String("pathText")) {
|
||||
QList<QList<TextRender>*> list;
|
||||
list.append(&_pathLabels);
|
||||
text(reader, r, list);
|
||||
} else if (reader.name() == QLatin1String("caption")) {
|
||||
QList<QList<TextRender>*> list;
|
||||
if (r._type == Rule::WayType || r._type == Rule::AnyType)
|
||||
list.append(&_areaLabels);
|
||||
if (r._type == Rule::NodeType || r._type == Rule::AnyType)
|
||||
list.append(&_pointLabels);
|
||||
text(reader, r, list);
|
||||
}
|
||||
else if (reader.name() == QLatin1String("symbol"))
|
||||
symbol(reader, dir, r);
|
||||
else
|
||||
@ -327,6 +345,50 @@ void Style::match(int zoom, bool closed, const QVector<MapData::Tag> &tags,
|
||||
ri->append(&_paths.at(i));
|
||||
}
|
||||
|
||||
QList<const Style::TextRender*> Style::pathLabels(int zoom) const
|
||||
{
|
||||
QList<const Style::TextRender*> list;
|
||||
|
||||
for (int i = 0; i < _pathLabels.size(); i++)
|
||||
if (_pathLabels.at(i).rule().zooms().contains(zoom))
|
||||
list.append(&_pathLabels.at(i));
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
QList<const Style::TextRender*> Style::pointLabels(int zoom) const
|
||||
{
|
||||
QList<const Style::TextRender*> list;
|
||||
|
||||
for (int i = 0; i < _pointLabels.size(); i++)
|
||||
if (_pointLabels.at(i).rule().zooms().contains(zoom))
|
||||
list.append(&_pointLabels.at(i));
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
QList<const Style::TextRender*> Style::areaLabels(int zoom) const
|
||||
{
|
||||
QList<const Style::TextRender*> list;
|
||||
|
||||
for (int i = 0; i < _areaLabels.size(); i++)
|
||||
if (_areaLabels.at(i).rule().zooms().contains(zoom))
|
||||
list.append(&_areaLabels.at(i));
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
QList<const Style::Symbol*> Style::symbols(int zoom) const
|
||||
{
|
||||
QList<const Style::Symbol*> list;
|
||||
|
||||
for (int i = 0; i < _symbols.size(); i++)
|
||||
if (_symbols.at(i).rule().zooms().contains(zoom))
|
||||
list.append(&_symbols.at(i));
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
QPen Style::PathRender::pen(int zoom) const
|
||||
{
|
||||
qreal width = (zoom >= 12)
|
||||
|
@ -29,9 +29,12 @@ public:
|
||||
public:
|
||||
Rule() : _type(AnyType), _closed(AnyClosed), _zooms(0, 127) {}
|
||||
|
||||
bool match(const QVector<MapData::Tag> &tags) const;
|
||||
bool match(bool closed, const QVector<MapData::Tag> &tags) const;
|
||||
bool match(int zoom, bool closed,
|
||||
const QVector<MapData::Tag> &tags) const;
|
||||
bool match(int zoom, const QVector<MapData::Tag> &tags) const;
|
||||
|
||||
const Range &zooms() const {return _zooms;}
|
||||
|
||||
private:
|
||||
enum Type {
|
||||
@ -214,13 +217,14 @@ public:
|
||||
|
||||
void match(int zoom, bool closed, const QVector<MapData::Tag> &tags,
|
||||
QVector<const PathRender *> *ri) const;
|
||||
const QList<TextRender> &pathLabels() const {return _pathLabels;}
|
||||
const QList<TextRender> &pointLabels() const {return _pointLabels;}
|
||||
const QList<Symbol> &symbols() const {return _symbols;}
|
||||
QList<const TextRender*> pathLabels(int zoom) const;
|
||||
QList<const TextRender*> pointLabels(int zoom) const;
|
||||
QList<const TextRender*> areaLabels(int zoom) const;
|
||||
QList<const Symbol*> symbols(int zoom) const;
|
||||
|
||||
private:
|
||||
QList<PathRender> _paths;
|
||||
QList<TextRender> _pathLabels, _pointLabels;
|
||||
QList<TextRender> _pathLabels, _pointLabels, _areaLabels;
|
||||
QList<Symbol> _symbols;
|
||||
|
||||
bool loadXml(const QString &path);
|
||||
@ -233,7 +237,7 @@ private:
|
||||
void area(QXmlStreamReader &reader, const QString &dir, const Rule &rule);
|
||||
void line(QXmlStreamReader &reader, const Rule &rule);
|
||||
void text(QXmlStreamReader &reader, const Rule &rule,
|
||||
QList<TextRender> &list);
|
||||
QList<QList<TextRender> *> &lists);
|
||||
void symbol(QXmlStreamReader &reader, const QString &dir, const Rule &rule);
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user