diff --git a/src/map/IMG/rastertile.cpp b/src/map/IMG/rastertile.cpp index df9e15ba..1378dd5c 100644 --- a/src/map/IMG/rastertile.cpp +++ b/src/map/IMG/rastertile.cpp @@ -136,7 +136,7 @@ static qreal area(const QVector &polygon) } area /= 2.0; - return area; + return area; } static QPointF centroid(const QVector &polygon) diff --git a/src/map/mapsforge/mapdata.cpp b/src/map/mapsforge/mapdata.cpp index 41465e65..d5756cd3 100644 --- a/src/map/mapsforge/mapdata.cpp +++ b/src/map/mapsforge/mapdata.cpp @@ -544,7 +544,7 @@ bool MapData::readPaths(const VectorTile *tile, int zoom, QList *list) QVector paths(rows); quint32 blocks, unused, val, cnt = 0; quint16 bitmap; - quint8 flags; + quint8 sb, flags; QByteArray label, houseNumber, reference; @@ -565,13 +565,14 @@ bool MapData::readPaths(const VectorTile *tile, int zoom, QList *list) for (unsigned i = 0; i < paths[zoom - info.min]; i++) { Path p; + qint32 lon = 0, lat = 0; if (!(subfile.readVUInt32(unused) && subfile.readUInt16(bitmap) - && subfile.readByte(flags))) + && subfile.readByte(sb))) return false; - p.layer = flags >> 4; - int tags = flags & 0x0F; + p.layer = sb >> 4; + int tags = sb & 0x0F; if (!readTags(subfile, tags, _pathTags, p.tags)) return false; @@ -592,8 +593,7 @@ bool MapData::readPaths(const VectorTile *tile, int zoom, QList *list) p.reference = reference; } if (flags & 0x10) { - qint32 unused; - if (!(subfile.readVInt32(unused) && subfile.readVInt32(unused))) + if (!(subfile.readVInt32(lat) && subfile.readVInt32(lon))) return false; } if (flags & 0x08) { @@ -607,6 +607,9 @@ bool MapData::readPaths(const VectorTile *tile, int zoom, QList *list) if (!readPolygon(subfile, tile->pos, flags & 0x04, p.poly)) return false; p.closed = isClosed(p.poly); + if (flags & 0x10) + p.labelPos = Coordinates(p.poly.first().first().lon() + MD(lon), + p.poly.first().first().lat() + MD(lat)); list->append(p); } @@ -622,7 +625,7 @@ bool MapData::readPoints(const VectorTile *tile, int zoom, QList *list) int rows = info.max - info.min + 1; QVector points(rows); quint32 val, unused, cnt = 0; - quint8 flags; + quint8 sb, flags; QByteArray label, houseNumber; @@ -647,10 +650,10 @@ bool MapData::readPoints(const VectorTile *tile, int zoom, QList *list) Point p(Coordinates(tile->pos.lon() + MD(lon), tile->pos.lat() + MD(lat))); - if (!subfile.readByte(flags)) + if (!subfile.readByte(sb)) return false; - p.layer = flags >> 4; - int tags = flags & 0x0F; + p.layer = sb >> 4; + int tags = sb & 0x0F; if (!readTags(subfile, tags, _pointTags, p.tags)) return false; diff --git a/src/map/mapsforge/mapdata.h b/src/map/mapsforge/mapdata.h index 9a49beaf..8e9712ae 100644 --- a/src/map/mapsforge/mapdata.h +++ b/src/map/mapsforge/mapdata.h @@ -57,6 +57,7 @@ public: QString label; QString reference; QVector tags; + Coordinates labelPos; int layer; bool closed; diff --git a/src/map/mapsforge/rastertile.cpp b/src/map/mapsforge/rastertile.cpp index da97c388..e1825b0f 100644 --- a/src/map/mapsforge/rastertile.cpp +++ b/src/map/mapsforge/rastertile.cpp @@ -14,6 +14,36 @@ static const Style& style() return s; } +static qreal area(const QPainterPath &polygon) +{ + qreal area = 0; + + for (int i = 0; i < polygon.elementCount(); i++) { + int j = (i + 1) % polygon.elementCount(); + area += polygon.elementAt(i).x * polygon.elementAt(j).y; + area -= polygon.elementAt(i).y * polygon.elementAt(j).x; + } + area /= 2.0; + + return area; +} + +static QPointF centroid(const QPainterPath &polygon) +{ + qreal cx = 0, cy = 0; + qreal factor = 1.0 / (6.0 * area(polygon)); + + for (int i = 0; i < polygon.elementCount(); i++) { + int j = (i + 1) % polygon.elementCount(); + qreal f = (polygon.elementAt(i).x * polygon.elementAt(j).y + - polygon.elementAt(j).x * polygon.elementAt(i).y); + cx += (polygon.elementAt(i).x + polygon.elementAt(j).x) * f; + cy += (polygon.elementAt(i).y + polygon.elementAt(j).y) * f; + } + + return QPointF(cx * factor, cy * factor); +} + void RasterTile::processPoints(QList &textItems) { const Style &s = style(); @@ -59,6 +89,42 @@ void RasterTile::processPoints(QList &textItems) } } +void RasterTile::processPolygonNames(const QRect &tileRect, + QList &textItems) +{ + const Style &s = style(); + QSet set; + + for (int i = 0; i < s.pointLabels().size(); i++) { + const Style::TextRender &ri = s.pointLabels().at(i); + + for (int j = 0; j < _paths.size(); j++) { + const MapData::Path &path = _paths.at(j); + + if (path.label.isEmpty()) + continue; + if (!path.path.elementCount()) + continue; + if (set.contains(path.label)) + continue; + if (!ri.rule().match(_zoom, 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); + if (item->isValid() && tileRect.contains(item->boundingRect().toRect()) + && !item->collides(textItems)) { + textItems.append(item); + set.insert(path.label); + } else + delete item; + } + } +} + void RasterTile::processStreetNames(const QRect &tileRect, QList &textItems) { @@ -173,6 +239,7 @@ void RasterTile::render() drawPaths(&painter); processPoints(textItems); + processPolygonNames(tileRect, textItems); processStreetNames(tileRect, textItems); drawTextItems(&painter, textItems); diff --git a/src/map/mapsforge/rastertile.h b/src/map/mapsforge/rastertile.h index bf7c3129..61ebf036 100644 --- a/src/map/mapsforge/rastertile.h +++ b/src/map/mapsforge/rastertile.h @@ -72,6 +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 processStreetNames(const QRect &tileRect, QList &textItems); QPainterPath painterPath(const Polygon &polygon) const; void drawTextItems(QPainter *painter, const QList &textItems);