mirror of
https://github.com/tumic0/GPXSee.git
synced 2024-11-30 22:51:16 +01:00
Added polygon labels rendering
This commit is contained in:
parent
983e68b880
commit
a42709e6a2
@ -544,7 +544,7 @@ bool MapData::readPaths(const VectorTile *tile, int zoom, QList<Path> *list)
|
|||||||
QVector<unsigned> paths(rows);
|
QVector<unsigned> paths(rows);
|
||||||
quint32 blocks, unused, val, cnt = 0;
|
quint32 blocks, unused, val, cnt = 0;
|
||||||
quint16 bitmap;
|
quint16 bitmap;
|
||||||
quint8 flags;
|
quint8 sb, flags;
|
||||||
QByteArray label, houseNumber, reference;
|
QByteArray label, houseNumber, reference;
|
||||||
|
|
||||||
|
|
||||||
@ -565,13 +565,14 @@ bool MapData::readPaths(const VectorTile *tile, int zoom, QList<Path> *list)
|
|||||||
|
|
||||||
for (unsigned i = 0; i < paths[zoom - info.min]; i++) {
|
for (unsigned i = 0; i < paths[zoom - info.min]; i++) {
|
||||||
Path p;
|
Path p;
|
||||||
|
qint32 lon = 0, lat = 0;
|
||||||
|
|
||||||
if (!(subfile.readVUInt32(unused) && subfile.readUInt16(bitmap)
|
if (!(subfile.readVUInt32(unused) && subfile.readUInt16(bitmap)
|
||||||
&& subfile.readByte(flags)))
|
&& subfile.readByte(sb)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
p.layer = flags >> 4;
|
p.layer = sb >> 4;
|
||||||
int tags = flags & 0x0F;
|
int tags = sb & 0x0F;
|
||||||
if (!readTags(subfile, tags, _pathTags, p.tags))
|
if (!readTags(subfile, tags, _pathTags, p.tags))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -592,8 +593,7 @@ bool MapData::readPaths(const VectorTile *tile, int zoom, QList<Path> *list)
|
|||||||
p.reference = reference;
|
p.reference = reference;
|
||||||
}
|
}
|
||||||
if (flags & 0x10) {
|
if (flags & 0x10) {
|
||||||
qint32 unused;
|
if (!(subfile.readVInt32(lat) && subfile.readVInt32(lon)))
|
||||||
if (!(subfile.readVInt32(unused) && subfile.readVInt32(unused)))
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (flags & 0x08) {
|
if (flags & 0x08) {
|
||||||
@ -607,6 +607,9 @@ bool MapData::readPaths(const VectorTile *tile, int zoom, QList<Path> *list)
|
|||||||
if (!readPolygon(subfile, tile->pos, flags & 0x04, p.poly))
|
if (!readPolygon(subfile, tile->pos, flags & 0x04, p.poly))
|
||||||
return false;
|
return false;
|
||||||
p.closed = isClosed(p.poly);
|
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);
|
list->append(p);
|
||||||
}
|
}
|
||||||
@ -622,7 +625,7 @@ bool MapData::readPoints(const VectorTile *tile, int zoom, QList<Point> *list)
|
|||||||
int rows = info.max - info.min + 1;
|
int rows = info.max - info.min + 1;
|
||||||
QVector<unsigned> points(rows);
|
QVector<unsigned> points(rows);
|
||||||
quint32 val, unused, cnt = 0;
|
quint32 val, unused, cnt = 0;
|
||||||
quint8 flags;
|
quint8 sb, flags;
|
||||||
QByteArray label, houseNumber;
|
QByteArray label, houseNumber;
|
||||||
|
|
||||||
|
|
||||||
@ -647,10 +650,10 @@ bool MapData::readPoints(const VectorTile *tile, int zoom, QList<Point> *list)
|
|||||||
Point p(Coordinates(tile->pos.lon() + MD(lon),
|
Point p(Coordinates(tile->pos.lon() + MD(lon),
|
||||||
tile->pos.lat() + MD(lat)));
|
tile->pos.lat() + MD(lat)));
|
||||||
|
|
||||||
if (!subfile.readByte(flags))
|
if (!subfile.readByte(sb))
|
||||||
return false;
|
return false;
|
||||||
p.layer = flags >> 4;
|
p.layer = sb >> 4;
|
||||||
int tags = flags & 0x0F;
|
int tags = sb & 0x0F;
|
||||||
if (!readTags(subfile, tags, _pointTags, p.tags))
|
if (!readTags(subfile, tags, _pointTags, p.tags))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -57,6 +57,7 @@ public:
|
|||||||
QString label;
|
QString label;
|
||||||
QString reference;
|
QString reference;
|
||||||
QVector<Tag> tags;
|
QVector<Tag> tags;
|
||||||
|
Coordinates labelPos;
|
||||||
int layer;
|
int layer;
|
||||||
bool closed;
|
bool closed;
|
||||||
|
|
||||||
|
@ -14,6 +14,36 @@ static const Style& style()
|
|||||||
return s;
|
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<TextItem*> &textItems)
|
void RasterTile::processPoints(QList<TextItem*> &textItems)
|
||||||
{
|
{
|
||||||
const Style &s = style();
|
const Style &s = style();
|
||||||
@ -59,6 +89,42 @@ void RasterTile::processPoints(QList<TextItem*> &textItems)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RasterTile::processPolygonNames(const QRect &tileRect,
|
||||||
|
QList<TextItem*> &textItems)
|
||||||
|
{
|
||||||
|
const Style &s = style();
|
||||||
|
QSet<QString> 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,
|
void RasterTile::processStreetNames(const QRect &tileRect,
|
||||||
QList<TextItem*> &textItems)
|
QList<TextItem*> &textItems)
|
||||||
{
|
{
|
||||||
@ -173,6 +239,7 @@ void RasterTile::render()
|
|||||||
drawPaths(&painter);
|
drawPaths(&painter);
|
||||||
|
|
||||||
processPoints(textItems);
|
processPoints(textItems);
|
||||||
|
processPolygonNames(tileRect, textItems);
|
||||||
processStreetNames(tileRect, textItems);
|
processStreetNames(tileRect, textItems);
|
||||||
drawTextItems(&painter, textItems);
|
drawTextItems(&painter, textItems);
|
||||||
|
|
||||||
|
@ -72,6 +72,7 @@ private:
|
|||||||
QPointF ll2xy(const Coordinates &c) const
|
QPointF ll2xy(const Coordinates &c) const
|
||||||
{return _transform.proj2img(_proj.ll2xy(c));}
|
{return _transform.proj2img(_proj.ll2xy(c));}
|
||||||
void processPoints(QList<TextItem*> &textItems);
|
void processPoints(QList<TextItem*> &textItems);
|
||||||
|
void processPolygonNames(const QRect &tileRect, QList<TextItem*> &textItems);
|
||||||
void processStreetNames(const QRect &tileRect, QList<TextItem*> &textItems);
|
void processStreetNames(const QRect &tileRect, QList<TextItem*> &textItems);
|
||||||
QPainterPath painterPath(const Polygon &polygon) const;
|
QPainterPath painterPath(const Polygon &polygon) const;
|
||||||
void drawTextItems(QPainter *painter, const QList<TextItem*> &textItems);
|
void drawTextItems(QPainter *painter, const QList<TextItem*> &textItems);
|
||||||
|
Loading…
Reference in New Issue
Block a user