From 848bde0f8032ad59a41eae18a27771d28a92ba4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20T=C5=AFma?= Date: Wed, 20 Nov 2024 09:13:59 +0100 Subject: [PATCH] Properly mix the way and node POIs --- data/style/style.xml | 8 +- src/map/mapsforge/mapdata.cpp | 69 ++++++++++++++--- src/map/mapsforge/mapdata.h | 11 ++- src/map/mapsforge/rastertile.cpp | 122 ++++++------------------------- src/map/mapsforge/rastertile.h | 36 +++++---- src/map/mapsforge/style.cpp | 51 +++---------- src/map/mapsforge/style.h | 15 ++-- 7 files changed, 135 insertions(+), 177 deletions(-) diff --git a/data/style/style.xml b/data/style/style.xml index 13260280..ca170c4c 100644 --- a/data/style/style.xml +++ b/data/style/style.xml @@ -82,7 +82,7 @@ - + @@ -187,12 +187,14 @@ - + + + - + diff --git a/src/map/mapsforge/mapdata.cpp b/src/map/mapsforge/mapdata.cpp index a3ae938a..38074bfe 100644 --- a/src/map/mapsforge/mapdata.cpp +++ b/src/map/mapsforge/mapdata.cpp @@ -19,6 +19,26 @@ using namespace Mapsforge; #define KEY_REF "ref" #define KEY_ELE "ele" + +static Coordinates centroid(const Polygon &polygon) +{ + double area = 0; + double cx = 0, cy = 0; + const QVector &v = polygon.first(); + + for (int i = 0; i < v.count(); i++) { + int j = (i == v.count() - 1) ? 0 : i + 1; + double f = (v.at(i).lon() * v.at(j).lat() - v.at(j).lon() * v.at(i).lat()); + area += f; + cx += (v.at(i).lon() + v.at(j).lon()) * f; + cy += (v.at(i).lat() + v.at(j).lat()) * f; + } + + double factor = 1.0 / (3.0 * area); + + return Coordinates(cx * factor, cy * factor); +} + static void copyPaths(const RectC &rect, const QList *src, QList *dst) { @@ -39,6 +59,16 @@ static void copyPoints(const RectC &rect, const QList *src, } } +static void copyPoints(const RectC &rect, const QList *src, + QList *dst) +{ + for (int i = 0; i < src->size(); i++) { + const MapData::Path &path = src->at(i); + if (path.closed && rect.contains(path.point.coordinates)) + dst->append(path.point); + } +} + static double distance(const Coordinates &c1, const Coordinates &c2) { return hypot(c1.lon() - c2.lon(), c1.lat() - c2.lat()); @@ -425,7 +455,7 @@ MapData::MapData(const QString &fileName) if (!readHeader(file)) return; - _pathCache.setMaxCost(256); + _pathCache.setMaxCost(512); _pointCache.setMaxCost(256); _valid = true; @@ -528,9 +558,9 @@ void MapData::points(const VectorTile *tile, const RectC &rect, int zoom, _pointLock.lock(); - QList *cached = _pointCache.object(key); + QList *tilePoints = _pointCache.object(key); - if (!cached) { + if (!tilePoints) { QList *p = new QList(); if (readPoints(tile, zoom, p)) { copyPoints(rect, p, list); @@ -538,9 +568,26 @@ void MapData::points(const VectorTile *tile, const RectC &rect, int zoom, } else delete p; } else - copyPoints(rect, cached, list); + copyPoints(rect, tilePoints, list); _pointLock.unlock(); + + + _pathLock.lock(); + + QList *tilePaths = _pathCache.object(key); + + if (!tilePaths) { + QList *p = new QList(); + if (readPaths(tile, zoom, p)) { + copyPoints(rect, p, list); + _pathCache.insert(key, p); + } else + delete p; + } else + copyPoints(rect, tilePaths, list); + + _pathLock.unlock(); } void MapData::paths(const RectC &searchRect, const RectC &boundsRect, int zoom, @@ -620,9 +667,9 @@ bool MapData::readPaths(const VectorTile *tile, int zoom, QList *list) && subfile.readByte(sb))) return false; - p.layer = sb >> 4; + p.point.layer = sb >> 4; int tags = sb & 0x0F; - if (!readTags(subfile, tags, _pathTags, p.tags)) + if (!readTags(subfile, tags, _pathTags, p.point.tags)) return false; if (!subfile.readByte(flags)) @@ -631,17 +678,17 @@ bool MapData::readPaths(const VectorTile *tile, int zoom, QList *list) if (!subfile.readString(name)) return false; name = name.split('\r').first(); - p.tags.append(Tag(ID_NAME, name)); + p.point.tags.append(Tag(ID_NAME, name)); } if (flags & 0x40) { if (!subfile.readString(houseNumber)) return false; - p.tags.append(Tag(ID_HOUSE, houseNumber)); + p.point.tags.append(Tag(ID_HOUSE, houseNumber)); } if (flags & 0x20) { if (!subfile.readString(reference)) return false; - p.tags.append(Tag(ID_REF, reference)); + p.point.tags.append(Tag(ID_REF, reference)); } if (flags & 0x10) { if (!(subfile.readVInt32(lat) && subfile.readVInt32(lon))) @@ -660,8 +707,10 @@ bool MapData::readPaths(const VectorTile *tile, int zoom, QList *list) const QVector &outline = p.poly.first(); p.closed = isClosed(outline); if (flags & 0x10) - p.labelPos = Coordinates(outline.first().lon() + MD(lon), + p.point.coordinates = Coordinates(outline.first().lon() + MD(lon), outline.first().lat() + MD(lat)); + else if (p.closed) + p.point.coordinates = centroid(p.poly); list->append(p); } diff --git a/src/map/mapsforge/mapdata.h b/src/map/mapsforge/mapdata.h index 49b1459a..5e698a9b 100644 --- a/src/map/mapsforge/mapdata.h +++ b/src/map/mapsforge/mapdata.h @@ -39,6 +39,8 @@ public: struct Point { Point(quint64 id) : id(id) {} + bool center() const {return (id & 1ULL<<63) != 0;} + quint64 id; Coordinates coordinates; QVector tags; @@ -46,17 +48,14 @@ public: }; struct Path { - Path(quint64 id) : id(id) {} + Path(quint64 id) : point(id | 1ULL<<63) {} - quint64 id; + Point point; Polygon poly; - QVector tags; - Coordinates labelPos; - int layer; bool closed; bool operator<(const Path &other) const - {return layer < other.layer;} + {return point.layer < other.point.layer;} }; RectC bounds() const; diff --git a/src/map/mapsforge/rastertile.cpp b/src/map/mapsforge/rastertile.cpp index a8483fbd..5ba33d90 100644 --- a/src/map/mapsforge/rastertile.cpp +++ b/src/map/mapsforge/rastertile.cpp @@ -16,33 +16,6 @@ using namespace Mapsforge; static double LIMIT = cos(deg2rad(170)); -static bool rectNearPolygon(const QRectF &tileRect, const QPainterPath &path, - const QRectF &rect) -{ - return ((tileRect.contains(rect) || path.boundingRect().contains(rect)) - && (path.contains(rect.topLeft()) || path.contains(rect.topRight()) - || path.contains(rect.bottomLeft()) || path.contains(rect.bottomRight()))); -} - -static QPointF centroid(const QPainterPath &polygon) -{ - qreal area = 0; - qreal cx = 0, cy = 0; - - for (int i = 0; i < polygon.elementCount(); i++) { - int j = (i == polygon.elementCount() - 1) ? 0 : i + 1; - qreal f = (polygon.elementAt(i).x * polygon.elementAt(j).y - - polygon.elementAt(j).x * polygon.elementAt(i).y); - area += f; - cx += (polygon.elementAt(i).x + polygon.elementAt(j).x) * f; - cy += (polygon.elementAt(i).y + polygon.elementAt(j).y) * f; - } - - qreal factor = 1.0 / (3.0 * area); - - return QPointF(cx * factor, cy * factor); -} - static const QByteArray *label(unsigned key, const QVector &tags) { for (int i = 0; i < tags.size(); i++) { @@ -102,13 +75,11 @@ static QPainterPath parallelPath(const QPainterPath &p, double dy) } void RasterTile::processLabels(const QList &points, - const QVector &paths, QList &textItems) const + QList &textItems) const { QList