diff --git a/src/map/mapsforge/rastertile.cpp b/src/map/mapsforge/rastertile.cpp index c2dd7915..bd79d49d 100644 --- a/src/map/mapsforge/rastertile.cpp +++ b/src/map/mapsforge/rastertile.cpp @@ -47,6 +47,8 @@ static QPointF centroid(const QPainterPath &polygon) void RasterTile::processPoints(QList &textItems) { const Style &s = style(); + QList labels(s.pointLabels(_zoom)); + QList 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 &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 &textItems) } } -void RasterTile::processPolygonNames(const QRect &tileRect, +void RasterTile::processAreaNames(const QRect &tileRect, QList &textItems) { const Style &s = style(); + QList instructions(s.areaLabels(_zoom)); QSet 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 &textItems) { const Style &s = style(); + QList 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::pathInstructions() void RasterTile::drawPaths(QPainter *painter) { QVector 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); } diff --git a/src/map/mapsforge/rastertile.h b/src/map/mapsforge/rastertile.h index b4a8dbc4..23f69b11 100644 --- a/src/map/mapsforge/rastertile.h +++ b/src/map/mapsforge/rastertile.h @@ -72,7 +72,7 @@ private: QPointF ll2xy(const Coordinates &c) const {return _transform.proj2img(_proj.ll2xy(c));} void processPoints(QList &textItems); - void processPolygonNames(const QRect &tileRect, QList &textItems); + void processAreaNames(const QRect &tileRect, QList &textItems); void processStreetNames(const QRect &tileRect, QList &textItems); QPainterPath painterPath(const Polygon &polygon) const; void drawTextItems(QPainter *painter, const QList &textItems); diff --git a/src/map/mapsforge/style.cpp b/src/map/mapsforge/style.cpp index 581dcfe3..bc06e625 100644 --- a/src/map/mapsforge/style.cpp +++ b/src/map/mapsforge/style.cpp @@ -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 &tags) const +bool Style::Rule::match(const QVector &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 &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 &tags) const +bool Style::Rule::match(int zoom, bool closed, + const QVector &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 &list) + QList*> &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*> list; + list.append(&_pathLabels); + text(reader, r, list); + } else if (reader.name() == QLatin1String("caption")) { + QList*> 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 &tags, ri->append(&_paths.at(i)); } +QList Style::pathLabels(int zoom) const +{ + QList 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 Style::pointLabels(int zoom) const +{ + QList 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 Style::areaLabels(int zoom) const +{ + QList 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 Style::symbols(int zoom) const +{ + QList 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) diff --git a/src/map/mapsforge/style.h b/src/map/mapsforge/style.h index d6cb4906..2f7bd28b 100644 --- a/src/map/mapsforge/style.h +++ b/src/map/mapsforge/style.h @@ -29,9 +29,12 @@ public: public: Rule() : _type(AnyType), _closed(AnyClosed), _zooms(0, 127) {} + bool match(const QVector &tags) const; + bool match(bool closed, const QVector &tags) const; bool match(int zoom, bool closed, const QVector &tags) const; - bool match(int zoom, const QVector &tags) const; + + const Range &zooms() const {return _zooms;} private: enum Type { @@ -214,13 +217,14 @@ public: void match(int zoom, bool closed, const QVector &tags, QVector *ri) const; - const QList &pathLabels() const {return _pathLabels;} - const QList &pointLabels() const {return _pointLabels;} - const QList &symbols() const {return _symbols;} + QList pathLabels(int zoom) const; + QList pointLabels(int zoom) const; + QList areaLabels(int zoom) const; + QList symbols(int zoom) const; private: QList _paths; - QList _pathLabels, _pointLabels; + QList _pathLabels, _pointLabels, _areaLabels; QList _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 &list); + QList *> &lists); void symbol(QXmlStreamReader &reader, const QString &dir, const Rule &rule); };