mirror of
https://github.com/tumic0/GPXSee.git
synced 2024-11-28 05:34:47 +01:00
Added polygon labels rendering
This commit is contained in:
parent
983e68b880
commit
a42709e6a2
@ -136,7 +136,7 @@ static qreal area(const QVector<QPointF> &polygon)
|
||||
}
|
||||
area /= 2.0;
|
||||
|
||||
return area;
|
||||
return area;
|
||||
}
|
||||
|
||||
static QPointF centroid(const QVector<QPointF> &polygon)
|
||||
|
@ -544,7 +544,7 @@ bool MapData::readPaths(const VectorTile *tile, int zoom, QList<Path> *list)
|
||||
QVector<unsigned> 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<Path> *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<Path> *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<Path> *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<Point> *list)
|
||||
int rows = info.max - info.min + 1;
|
||||
QVector<unsigned> 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<Point> *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;
|
||||
|
||||
|
@ -57,6 +57,7 @@ public:
|
||||
QString label;
|
||||
QString reference;
|
||||
QVector<Tag> tags;
|
||||
Coordinates labelPos;
|
||||
int layer;
|
||||
bool closed;
|
||||
|
||||
|
@ -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<TextItem*> &textItems)
|
||||
{
|
||||
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,
|
||||
QList<TextItem*> &textItems)
|
||||
{
|
||||
@ -173,6 +239,7 @@ void RasterTile::render()
|
||||
drawPaths(&painter);
|
||||
|
||||
processPoints(textItems);
|
||||
processPolygonNames(tileRect, textItems);
|
||||
processStreetNames(tileRect, textItems);
|
||||
drawTextItems(&painter, textItems);
|
||||
|
||||
|
@ -72,6 +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 processStreetNames(const QRect &tileRect, QList<TextItem*> &textItems);
|
||||
QPainterPath painterPath(const Polygon &polygon) const;
|
||||
void drawTextItems(QPainter *painter, const QList<TextItem*> &textItems);
|
||||
|
Loading…
Reference in New Issue
Block a user