mirror of
https://github.com/tumic0/GPXSee.git
synced 2024-11-24 03:35:53 +01:00
Properly mix the way and node POIs
This commit is contained in:
parent
5d3d2d7571
commit
848bde0f80
@ -82,7 +82,7 @@
|
|||||||
<!-- Water -->
|
<!-- Water -->
|
||||||
<rule e="way" closed="yes" k="natural" v="water">
|
<rule e="way" closed="yes" k="natural" v="water">
|
||||||
<area fill="#9fc4e1"/>
|
<area fill="#9fc4e1"/>
|
||||||
<rule e="way" k="*" v="*" zoom-min="10">
|
<rule e="way" k="*" v="*" zoom-min="14">
|
||||||
<caption fill="#ffffff" font-size="12" font-family="serif" font-style="italic" k="name" stroke="#9fc4e1" stroke-width="2"/>
|
<caption fill="#ffffff" font-size="12" font-family="serif" font-style="italic" k="name" stroke="#9fc4e1" stroke-width="2"/>
|
||||||
</rule>
|
</rule>
|
||||||
</rule>
|
</rule>
|
||||||
@ -187,12 +187,14 @@
|
|||||||
<!-- Area overlays -->
|
<!-- Area overlays -->
|
||||||
<rule e="way" k="landuse" v="military" zoom-min="10">
|
<rule e="way" k="landuse" v="military" zoom-min="10">
|
||||||
<area src=":/patterns/military-area.svg" symbol-height="4"/>
|
<area src=":/patterns/military-area.svg" symbol-height="4"/>
|
||||||
<caption fill="#ff4040" font-size="10" font-style="italic" text-transform="uppercase" k="name" stroke="#ffffff" stroke-width="2"/>
|
<rule e="way" k="*" v="*" zoom-min="12">
|
||||||
|
<caption fill="#ff4040" font-size="10" font-style="italic" text-transform="uppercase" k="name" stroke="#ffffff" stroke-width="2"/>
|
||||||
|
</rule>
|
||||||
</rule>
|
</rule>
|
||||||
<rule e="way" k="boundary" v="protected_area|national_park" zoom-min="10" zoom-max="14">
|
<rule e="way" k="boundary" v="protected_area|national_park" zoom-min="10" zoom-max="14">
|
||||||
<rule e="way" k="protect_class" v="pr_2">
|
<rule e="way" k="protect_class" v="pr_2">
|
||||||
<area src=":/patterns/nature-reserve.svg" symbol-height="4"/>
|
<area src=":/patterns/nature-reserve.svg" symbol-height="4"/>
|
||||||
<rule e="way" k="*" v="*" zoom-max="12">
|
<rule e="way" k="*" v="*" zoom-max="11">
|
||||||
<caption fill="#9ac269" font-size="10" font-style="italic" text-transform="uppercase" k="name" stroke="#ffffff" stroke-width="2"/>
|
<caption fill="#9ac269" font-size="10" font-style="italic" text-transform="uppercase" k="name" stroke="#ffffff" stroke-width="2"/>
|
||||||
</rule>
|
</rule>
|
||||||
</rule>
|
</rule>
|
||||||
|
@ -19,6 +19,26 @@ using namespace Mapsforge;
|
|||||||
#define KEY_REF "ref"
|
#define KEY_REF "ref"
|
||||||
#define KEY_ELE "ele"
|
#define KEY_ELE "ele"
|
||||||
|
|
||||||
|
|
||||||
|
static Coordinates centroid(const Polygon &polygon)
|
||||||
|
{
|
||||||
|
double area = 0;
|
||||||
|
double cx = 0, cy = 0;
|
||||||
|
const QVector<Coordinates> &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<MapData::Path> *src,
|
static void copyPaths(const RectC &rect, const QList<MapData::Path> *src,
|
||||||
QList<MapData::Path> *dst)
|
QList<MapData::Path> *dst)
|
||||||
{
|
{
|
||||||
@ -39,6 +59,16 @@ static void copyPoints(const RectC &rect, const QList<MapData::Point> *src,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void copyPoints(const RectC &rect, const QList<MapData::Path> *src,
|
||||||
|
QList<MapData::Point> *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)
|
static double distance(const Coordinates &c1, const Coordinates &c2)
|
||||||
{
|
{
|
||||||
return hypot(c1.lon() - c2.lon(), c1.lat() - c2.lat());
|
return hypot(c1.lon() - c2.lon(), c1.lat() - c2.lat());
|
||||||
@ -425,7 +455,7 @@ MapData::MapData(const QString &fileName)
|
|||||||
if (!readHeader(file))
|
if (!readHeader(file))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_pathCache.setMaxCost(256);
|
_pathCache.setMaxCost(512);
|
||||||
_pointCache.setMaxCost(256);
|
_pointCache.setMaxCost(256);
|
||||||
|
|
||||||
_valid = true;
|
_valid = true;
|
||||||
@ -528,9 +558,9 @@ void MapData::points(const VectorTile *tile, const RectC &rect, int zoom,
|
|||||||
|
|
||||||
_pointLock.lock();
|
_pointLock.lock();
|
||||||
|
|
||||||
QList<Point> *cached = _pointCache.object(key);
|
QList<Point> *tilePoints = _pointCache.object(key);
|
||||||
|
|
||||||
if (!cached) {
|
if (!tilePoints) {
|
||||||
QList<Point> *p = new QList<Point>();
|
QList<Point> *p = new QList<Point>();
|
||||||
if (readPoints(tile, zoom, p)) {
|
if (readPoints(tile, zoom, p)) {
|
||||||
copyPoints(rect, p, list);
|
copyPoints(rect, p, list);
|
||||||
@ -538,9 +568,26 @@ void MapData::points(const VectorTile *tile, const RectC &rect, int zoom,
|
|||||||
} else
|
} else
|
||||||
delete p;
|
delete p;
|
||||||
} else
|
} else
|
||||||
copyPoints(rect, cached, list);
|
copyPoints(rect, tilePoints, list);
|
||||||
|
|
||||||
_pointLock.unlock();
|
_pointLock.unlock();
|
||||||
|
|
||||||
|
|
||||||
|
_pathLock.lock();
|
||||||
|
|
||||||
|
QList<Path> *tilePaths = _pathCache.object(key);
|
||||||
|
|
||||||
|
if (!tilePaths) {
|
||||||
|
QList<Path> *p = new QList<Path>();
|
||||||
|
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,
|
void MapData::paths(const RectC &searchRect, const RectC &boundsRect, int zoom,
|
||||||
@ -620,9 +667,9 @@ bool MapData::readPaths(const VectorTile *tile, int zoom, QList<Path> *list)
|
|||||||
&& subfile.readByte(sb)))
|
&& subfile.readByte(sb)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
p.layer = sb >> 4;
|
p.point.layer = sb >> 4;
|
||||||
int tags = sb & 0x0F;
|
int tags = sb & 0x0F;
|
||||||
if (!readTags(subfile, tags, _pathTags, p.tags))
|
if (!readTags(subfile, tags, _pathTags, p.point.tags))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!subfile.readByte(flags))
|
if (!subfile.readByte(flags))
|
||||||
@ -631,17 +678,17 @@ bool MapData::readPaths(const VectorTile *tile, int zoom, QList<Path> *list)
|
|||||||
if (!subfile.readString(name))
|
if (!subfile.readString(name))
|
||||||
return false;
|
return false;
|
||||||
name = name.split('\r').first();
|
name = name.split('\r').first();
|
||||||
p.tags.append(Tag(ID_NAME, name));
|
p.point.tags.append(Tag(ID_NAME, name));
|
||||||
}
|
}
|
||||||
if (flags & 0x40) {
|
if (flags & 0x40) {
|
||||||
if (!subfile.readString(houseNumber))
|
if (!subfile.readString(houseNumber))
|
||||||
return false;
|
return false;
|
||||||
p.tags.append(Tag(ID_HOUSE, houseNumber));
|
p.point.tags.append(Tag(ID_HOUSE, houseNumber));
|
||||||
}
|
}
|
||||||
if (flags & 0x20) {
|
if (flags & 0x20) {
|
||||||
if (!subfile.readString(reference))
|
if (!subfile.readString(reference))
|
||||||
return false;
|
return false;
|
||||||
p.tags.append(Tag(ID_REF, reference));
|
p.point.tags.append(Tag(ID_REF, reference));
|
||||||
}
|
}
|
||||||
if (flags & 0x10) {
|
if (flags & 0x10) {
|
||||||
if (!(subfile.readVInt32(lat) && subfile.readVInt32(lon)))
|
if (!(subfile.readVInt32(lat) && subfile.readVInt32(lon)))
|
||||||
@ -660,8 +707,10 @@ bool MapData::readPaths(const VectorTile *tile, int zoom, QList<Path> *list)
|
|||||||
const QVector<Coordinates> &outline = p.poly.first();
|
const QVector<Coordinates> &outline = p.poly.first();
|
||||||
p.closed = isClosed(outline);
|
p.closed = isClosed(outline);
|
||||||
if (flags & 0x10)
|
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));
|
outline.first().lat() + MD(lat));
|
||||||
|
else if (p.closed)
|
||||||
|
p.point.coordinates = centroid(p.poly);
|
||||||
|
|
||||||
list->append(p);
|
list->append(p);
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,8 @@ public:
|
|||||||
struct Point {
|
struct Point {
|
||||||
Point(quint64 id) : id(id) {}
|
Point(quint64 id) : id(id) {}
|
||||||
|
|
||||||
|
bool center() const {return (id & 1ULL<<63) != 0;}
|
||||||
|
|
||||||
quint64 id;
|
quint64 id;
|
||||||
Coordinates coordinates;
|
Coordinates coordinates;
|
||||||
QVector<Tag> tags;
|
QVector<Tag> tags;
|
||||||
@ -46,17 +48,14 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Path {
|
struct Path {
|
||||||
Path(quint64 id) : id(id) {}
|
Path(quint64 id) : point(id | 1ULL<<63) {}
|
||||||
|
|
||||||
quint64 id;
|
Point point;
|
||||||
Polygon poly;
|
Polygon poly;
|
||||||
QVector<Tag> tags;
|
|
||||||
Coordinates labelPos;
|
|
||||||
int layer;
|
|
||||||
bool closed;
|
bool closed;
|
||||||
|
|
||||||
bool operator<(const Path &other) const
|
bool operator<(const Path &other) const
|
||||||
{return layer < other.layer;}
|
{return point.layer < other.point.layer;}
|
||||||
};
|
};
|
||||||
|
|
||||||
RectC bounds() const;
|
RectC bounds() const;
|
||||||
|
@ -16,33 +16,6 @@ using namespace Mapsforge;
|
|||||||
|
|
||||||
static double LIMIT = cos(deg2rad(170));
|
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<MapData::Tag> &tags)
|
static const QByteArray *label(unsigned key, const QVector<MapData::Tag> &tags)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < tags.size(); i++) {
|
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<MapData::Point> &points,
|
void RasterTile::processLabels(const QList<MapData::Point> &points,
|
||||||
const QVector<PainterPath> &paths, QList<TextItem*> &textItems) const
|
QList<TextItem*> &textItems) const
|
||||||
{
|
{
|
||||||
QList<Label> items;
|
QList<Label> items;
|
||||||
QList<const Style::TextRender*> pointLabels(_style->pointLabels(_zoom));
|
QList<const Style::TextRender*> labels(_style->labels(_zoom));
|
||||||
QList<const Style::Symbol*> pointSymbols(_style->pointSymbols(_zoom));
|
QList<const Style::Symbol*> symbols(_style->symbols(_zoom));
|
||||||
QList<const Style::TextRender*> areaLabels(_style->areaLabels(_zoom));
|
|
||||||
QList<const Style::Symbol*> areaSymbols(_style->areaSymbols(_zoom));
|
|
||||||
|
|
||||||
for (int i = 0; i < points.size(); i++) {
|
for (int i = 0; i < points.size(); i++) {
|
||||||
const MapData::Point &point = points.at(i);
|
const MapData::Point &point = points.at(i);
|
||||||
@ -116,17 +87,17 @@ void RasterTile::processLabels(const QList<MapData::Point> &points,
|
|||||||
const Style::Symbol *si = 0;
|
const Style::Symbol *si = 0;
|
||||||
const QByteArray *lbl = 0;
|
const QByteArray *lbl = 0;
|
||||||
|
|
||||||
for (int j = 0; j < pointSymbols.size(); j++) {
|
for (int j = 0; j < symbols.size(); j++) {
|
||||||
const Style::Symbol *ri = pointSymbols.at(j);
|
const Style::Symbol *ri = symbols.at(j);
|
||||||
if (ri->rule().match(point.tags)) {
|
if (ri->rule().match(point.center(), point.tags)) {
|
||||||
si = ri;
|
si = ri;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < pointLabels.size(); j++) {
|
for (int j = 0; j < labels.size(); j++) {
|
||||||
const Style::TextRender *ri = pointLabels.at(j);
|
const Style::TextRender *ri = labels.at(j);
|
||||||
if (ri->rule().match(point.tags)) {
|
if (ri->rule().match(point.center(), point.tags)) {
|
||||||
if ((lbl = label(ri->key(), point.tags))) {
|
if ((lbl = label(ri->key(), point.tags))) {
|
||||||
if (!si || si->id() == ri->symbolId()) {
|
if (!si || si->id() == ri->symbolId()) {
|
||||||
ti = ri;
|
ti = ri;
|
||||||
@ -140,39 +111,6 @@ void RasterTile::processLabels(const QList<MapData::Point> &points,
|
|||||||
items.append(Label(&point, lbl, si, ti));
|
items.append(Label(&point, lbl, si, ti));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < paths.size(); i++) {
|
|
||||||
const PainterPath &path = paths.at(i);
|
|
||||||
const Style::TextRender *ti = 0;
|
|
||||||
const Style::Symbol *si = 0;
|
|
||||||
const QByteArray *lbl = 0;
|
|
||||||
|
|
||||||
if (!path.path->closed)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (int j = 0; j < areaSymbols.size(); j++) {
|
|
||||||
const Style::Symbol *ri = areaSymbols.at(j);
|
|
||||||
if (ri->rule().match(path.path->closed, path.path->tags)) {
|
|
||||||
si = ri;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int j = 0; j < areaLabels.size(); j++) {
|
|
||||||
const Style::TextRender *ri = areaLabels.at(j);
|
|
||||||
if (ri->rule().match(path.path->closed, path.path->tags)) {
|
|
||||||
if ((lbl = label(ri->key(), path.path->tags))) {
|
|
||||||
if (!si || si->id() == ri->symbolId()) {
|
|
||||||
ti = ri;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ti || si)
|
|
||||||
items.append(Label(&path, lbl, si, ti));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::sort(items.begin(), items.end());
|
std::sort(items.begin(), items.end());
|
||||||
|
|
||||||
for (int i = 0; i < items.size(); i++) {
|
for (int i = 0; i < items.size(); i++) {
|
||||||
@ -182,24 +120,12 @@ void RasterTile::processLabels(const QList<MapData::Point> &points,
|
|||||||
const QColor *color = l.ti ? &l.ti->fillColor() : 0;
|
const QColor *color = l.ti ? &l.ti->fillColor() : 0;
|
||||||
const QColor *hColor = l.ti ? haloColor(l.ti) : 0;
|
const QColor *hColor = l.ti ? haloColor(l.ti) : 0;
|
||||||
|
|
||||||
if (l.point) {
|
PointItem *item = new PointItem(ll2xy(l.point->coordinates).toPoint(),
|
||||||
PointItem *item = new PointItem(ll2xy(l.point->coordinates).toPoint(),
|
l.lbl, font, img, color, hColor);
|
||||||
l.lbl, font, img, color, hColor);
|
if (item->isValid() && !item->collides(textItems))
|
||||||
if (item->isValid() && !item->collides(textItems))
|
textItems.append(item);
|
||||||
textItems.append(item);
|
else
|
||||||
else
|
delete item;
|
||||||
delete item;
|
|
||||||
} else {
|
|
||||||
QPointF pos = l.path->path->labelPos.isNull()
|
|
||||||
? centroid(l.path->pp) : ll2xy(l.path->path->labelPos);
|
|
||||||
PointItem *item = new PointItem(pos.toPoint(), l.lbl, font, img,
|
|
||||||
color, hColor);
|
|
||||||
if (item->isValid() && rectNearPolygon(_rect, l.path->pp,
|
|
||||||
item->boundingRect()) && !item->collides(textItems))
|
|
||||||
textItems.append(item);
|
|
||||||
else
|
|
||||||
delete item;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,7 +134,7 @@ void RasterTile::processLineLabels(const QVector<PainterPath> &paths,
|
|||||||
{
|
{
|
||||||
QList<const Style::TextRender*> labels(_style->pathLabels(_zoom));
|
QList<const Style::TextRender*> labels(_style->pathLabels(_zoom));
|
||||||
QList<const Style::Symbol*> symbols(_style->lineSymbols(_zoom));
|
QList<const Style::Symbol*> symbols(_style->lineSymbols(_zoom));
|
||||||
QList<Label> items;
|
QList<LineLabel> items;
|
||||||
QSet<QByteArray> set;
|
QSet<QByteArray> set;
|
||||||
|
|
||||||
for (int i = 0; i < paths.size(); i++) {
|
for (int i = 0; i < paths.size(); i++) {
|
||||||
@ -222,7 +148,7 @@ void RasterTile::processLineLabels(const QVector<PainterPath> &paths,
|
|||||||
|
|
||||||
for (int j = 0; j < symbols.size(); j++) {
|
for (int j = 0; j < symbols.size(); j++) {
|
||||||
const Style::Symbol *ri = symbols.at(j);
|
const Style::Symbol *ri = symbols.at(j);
|
||||||
if (ri->rule().match(path.path->closed, path.path->tags)) {
|
if (ri->rule().matchPath(path.path->closed, path.path->point.tags)) {
|
||||||
si = ri;
|
si = ri;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -230,8 +156,8 @@ void RasterTile::processLineLabels(const QVector<PainterPath> &paths,
|
|||||||
|
|
||||||
for (int j = 0; j < labels.size(); j++) {
|
for (int j = 0; j < labels.size(); j++) {
|
||||||
const Style::TextRender *ri = labels.at(j);
|
const Style::TextRender *ri = labels.at(j);
|
||||||
if (ri->rule().match(path.path->closed, path.path->tags)) {
|
if (ri->rule().matchPath(path.path->closed, path.path->point.tags)) {
|
||||||
if ((lbl = label(ri->key(), path.path->tags))) {
|
if ((lbl = label(ri->key(), path.path->point.tags))) {
|
||||||
if (!si || si->id() == ri->symbolId()) {
|
if (!si || si->id() == ri->symbolId()) {
|
||||||
ti = ri;
|
ti = ri;
|
||||||
break;
|
break;
|
||||||
@ -241,13 +167,13 @@ void RasterTile::processLineLabels(const QVector<PainterPath> &paths,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ti || si)
|
if (ti || si)
|
||||||
items.append(Label(&path, lbl, si, ti));
|
items.append(LineLabel(&path, lbl, si, ti));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::sort(items.begin(), items.end());
|
std::sort(items.begin(), items.end());
|
||||||
|
|
||||||
for (int i = 0; i < items.size(); i++) {
|
for (int i = 0; i < items.size(); i++) {
|
||||||
const Label &l = items.at(i);
|
const LineLabel &l = items.at(i);
|
||||||
const QImage *img = l.si ? &l.si->img() : 0;
|
const QImage *img = l.si ? &l.si->img() : 0;
|
||||||
const QFont *font = l.ti ? &l.ti->font() : 0;
|
const QFont *font = l.ti ? &l.ti->font() : 0;
|
||||||
const QColor *color = l.ti ? &l.ti->fillColor() : 0;
|
const QColor *color = l.ti ? &l.ti->fillColor() : 0;
|
||||||
@ -361,13 +287,13 @@ void RasterTile::pathInstructions(const QList<MapData::Path> &paths,
|
|||||||
for (int i = 0; i < paths.size(); i++) {
|
for (int i = 0; i < paths.size(); i++) {
|
||||||
const MapData::Path &path = paths.at(i);
|
const MapData::Path &path = paths.at(i);
|
||||||
PainterPath &rp = painterPaths[i];
|
PainterPath &rp = painterPaths[i];
|
||||||
PathKey key(_zoom, path.closed, path.tags);
|
PathKey key(_zoom, path.closed, path.point.tags);
|
||||||
|
|
||||||
rp.path = &path;
|
rp.path = &path;
|
||||||
|
|
||||||
if (!(ri = cache.object(key))) {
|
if (!(ri = cache.object(key))) {
|
||||||
ri = new QList<const Style::PathRender*>(_style->paths(_zoom,
|
ri = new QList<const Style::PathRender*>(_style->paths(_zoom,
|
||||||
path.closed, path.tags));
|
path.closed, path.point.tags));
|
||||||
for (int j = 0; j < ri->size(); j++)
|
for (int j = 0; j < ri->size(); j++)
|
||||||
instructions.append(RenderInstruction(ri->at(j), &rp));
|
instructions.append(RenderInstruction(ri->at(j), &rp));
|
||||||
cache.insert(key, ri);
|
cache.insert(key, ri);
|
||||||
@ -530,7 +456,7 @@ void RasterTile::render()
|
|||||||
|
|
||||||
drawPaths(&painter, paths, points, renderPaths);
|
drawPaths(&painter, paths, points, renderPaths);
|
||||||
|
|
||||||
processLabels(points, renderPaths, textItems);
|
processLabels(points, textItems);
|
||||||
processLineLabels(renderPaths, textItems);
|
processLineLabels(renderPaths, textItems);
|
||||||
drawTextItems(&painter, textItems);
|
drawTextItems(&painter, textItems);
|
||||||
|
|
||||||
|
@ -46,30 +46,40 @@ private:
|
|||||||
struct Label {
|
struct Label {
|
||||||
Label(const MapData::Point *p, const QByteArray *lbl,
|
Label(const MapData::Point *p, const QByteArray *lbl,
|
||||||
const Style::Symbol *si, const Style::TextRender *ti)
|
const Style::Symbol *si, const Style::TextRender *ti)
|
||||||
: point(p), path(0), lbl(lbl), ti(ti), si(si)
|
: point(p), lbl(lbl), ti(ti), si(si)
|
||||||
{
|
|
||||||
Q_ASSERT(si || ti);
|
|
||||||
}
|
|
||||||
Label(const PainterPath *p, const QByteArray *lbl,
|
|
||||||
const Style::Symbol *si, const Style::TextRender *ti)
|
|
||||||
: point(0), path(p), lbl(lbl), ti(ti), si(si)
|
|
||||||
{
|
{
|
||||||
Q_ASSERT(si || ti);
|
Q_ASSERT(si || ti);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator<(const Label &other) const
|
bool operator<(const Label &other) const
|
||||||
{
|
{
|
||||||
quint64 id = point ? point->id : path->path->id;
|
|
||||||
quint64 oid = other.point ? other.point->id : other.path->path->id;
|
|
||||||
|
|
||||||
if (priority() == other.priority())
|
if (priority() == other.priority())
|
||||||
return id < oid;
|
return point->id < other.point->id;
|
||||||
else
|
else
|
||||||
return (priority() > other.priority());
|
return (priority() > other.priority());
|
||||||
}
|
}
|
||||||
int priority() const {return si ? si->priority() : ti->priority();}
|
int priority() const {return si ? si->priority() : ti->priority();}
|
||||||
|
|
||||||
const MapData::Point *point;
|
const MapData::Point *point;
|
||||||
|
const QByteArray *lbl;
|
||||||
|
const Style::TextRender *ti;
|
||||||
|
const Style::Symbol *si;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LineLabel {
|
||||||
|
LineLabel(const PainterPath *p, const QByteArray *lbl,
|
||||||
|
const Style::Symbol *si, const Style::TextRender *ti)
|
||||||
|
: path(p), lbl(lbl), ti(ti), si(si)
|
||||||
|
{
|
||||||
|
Q_ASSERT(si || ti);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator<(const LineLabel &other) const
|
||||||
|
{
|
||||||
|
return (priority() > other.priority());
|
||||||
|
}
|
||||||
|
int priority() const {return si ? si->priority() : ti->priority();}
|
||||||
|
|
||||||
const PainterPath *path;
|
const PainterPath *path;
|
||||||
const QByteArray *lbl;
|
const QByteArray *lbl;
|
||||||
const Style::TextRender *ti;
|
const Style::TextRender *ti;
|
||||||
@ -110,7 +120,7 @@ private:
|
|||||||
int layer() const
|
int layer() const
|
||||||
{
|
{
|
||||||
if (_path)
|
if (_path)
|
||||||
return _path->path->layer;
|
return _path->path->point.layer;
|
||||||
else if (_point)
|
else if (_point)
|
||||||
return _point->layer;
|
return _point->layer;
|
||||||
else
|
else
|
||||||
@ -199,7 +209,7 @@ private:
|
|||||||
Coordinates xy2ll(const QPointF &p) const
|
Coordinates xy2ll(const QPointF &p) const
|
||||||
{return _proj.xy2ll(_transform.img2proj(p));}
|
{return _proj.xy2ll(_transform.img2proj(p));}
|
||||||
void processLabels(const QList<MapData::Point> &points,
|
void processLabels(const QList<MapData::Point> &points,
|
||||||
const QVector<PainterPath> &paths, QList<TextItem*> &textItems) const;
|
QList<TextItem*> &textItems) const;
|
||||||
void processLineLabels(const QVector<PainterPath> &paths,
|
void processLineLabels(const QVector<PainterPath> &paths,
|
||||||
QList<TextItem*> &textItems) const;
|
QList<TextItem*> &textItems) const;
|
||||||
QPainterPath painterPath(const Polygon &polygon, bool curve) const;
|
QPainterPath painterPath(const Polygon &polygon, bool curve) const;
|
||||||
|
@ -126,8 +126,13 @@ Style::Rule::Filter::Filter(const MapData &data, const QList<QByteArray> &keys,
|
|||||||
_vals = valList(vc);
|
_vals = valList(vc);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Style::Rule::match(const QVector<MapData::Tag> &tags) const
|
bool Style::Rule::match(bool path, const QVector<MapData::Tag> &tags) const
|
||||||
{
|
{
|
||||||
|
Type type = path ? WayType : NodeType;
|
||||||
|
|
||||||
|
if (!(_type == Rule::AnyType || _type == type))
|
||||||
|
return false;
|
||||||
|
|
||||||
for (int i = 0; i < _filters.size(); i++)
|
for (int i = 0; i < _filters.size(); i++)
|
||||||
if (!_filters.at(i).match(tags))
|
if (!_filters.at(i).match(tags))
|
||||||
return false;
|
return false;
|
||||||
@ -135,7 +140,7 @@ bool Style::Rule::match(const QVector<MapData::Tag> &tags) const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Style::Rule::match(bool closed, const QVector<MapData::Tag> &tags) const
|
bool Style::Rule::matchPath(bool closed, const QVector<MapData::Tag> &tags) const
|
||||||
{
|
{
|
||||||
Closed cl = closed ? YesClosed : NoClosed;
|
Closed cl = closed ? YesClosed : NoClosed;
|
||||||
|
|
||||||
@ -858,30 +863,13 @@ QList<const Style::TextRender*> Style::pathLabels(int zoom) const
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<const Style::TextRender*> Style::pointLabels(int zoom) const
|
QList<const Style::TextRender*> Style::labels(int zoom) const
|
||||||
{
|
{
|
||||||
QList<const TextRender*> list;
|
QList<const TextRender*> list;
|
||||||
|
|
||||||
for (int i = 0; i < _labels.size(); i++) {
|
for (int i = 0; i < _labels.size(); i++) {
|
||||||
const TextRender &label= _labels.at(i);
|
const TextRender &label= _labels.at(i);
|
||||||
const Rule &rule = label.rule();
|
if (label.rule()._zooms.contains(zoom))
|
||||||
if (rule._zooms.contains(zoom) && (rule._type == Rule::AnyType
|
|
||||||
|| rule._type == Rule::NodeType))
|
|
||||||
list.append(&label);
|
|
||||||
}
|
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<const Style::TextRender*> Style::areaLabels(int zoom) const
|
|
||||||
{
|
|
||||||
QList<const TextRender*> list;
|
|
||||||
|
|
||||||
for (int i = 0; i < _labels.size(); i++) {
|
|
||||||
const TextRender &label= _labels.at(i);
|
|
||||||
const Rule &rule = label.rule();
|
|
||||||
if (rule._zooms.contains(zoom) && (rule._type == Rule::AnyType
|
|
||||||
|| rule._type == Rule::WayType))
|
|
||||||
list.append(&label);
|
list.append(&label);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -901,30 +889,13 @@ QList<const Style::Symbol*> Style::lineSymbols(int zoom) const
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<const Style::Symbol*> Style::pointSymbols(int zoom) const
|
QList<const Style::Symbol*> Style::symbols(int zoom) const
|
||||||
{
|
{
|
||||||
QList<const Symbol*> list;
|
QList<const Symbol*> list;
|
||||||
|
|
||||||
for (int i = 0; i < _symbols.size(); i++) {
|
for (int i = 0; i < _symbols.size(); i++) {
|
||||||
const Symbol &symbol = _symbols.at(i);
|
const Symbol &symbol = _symbols.at(i);
|
||||||
const Rule &rule = symbol.rule();
|
if (symbol.rule()._zooms.contains(zoom))
|
||||||
if (rule._zooms.contains(zoom) && (rule._type == Rule::AnyType
|
|
||||||
|| rule._type == Rule::NodeType))
|
|
||||||
list.append(&symbol);
|
|
||||||
}
|
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<const Style::Symbol*> Style::areaSymbols(int zoom) const
|
|
||||||
{
|
|
||||||
QList<const Symbol*> list;
|
|
||||||
|
|
||||||
for (int i = 0; i < _symbols.size(); i++) {
|
|
||||||
const Symbol &symbol = _symbols.at(i);
|
|
||||||
const Rule &rule = symbol.rule();
|
|
||||||
if (rule._zooms.contains(zoom) && (rule._type == Rule::AnyType
|
|
||||||
|| rule._type == Rule::WayType))
|
|
||||||
list.append(&symbol);
|
list.append(&symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,11 +18,8 @@ public:
|
|||||||
public:
|
public:
|
||||||
Rule() : _type(AnyType), _closed(AnyClosed), _zooms(0, 127) {}
|
Rule() : _type(AnyType), _closed(AnyClosed), _zooms(0, 127) {}
|
||||||
|
|
||||||
bool match(const QVector<MapData::Tag> &tags) const;
|
bool match(bool path, const QVector<MapData::Tag> &tags) const;
|
||||||
bool match(bool closed, const QVector<MapData::Tag> &tags) const;
|
bool matchPath(bool closed, const QVector<MapData::Tag> &tags) const;
|
||||||
bool match(int zoom, bool closed,
|
|
||||||
const QVector<MapData::Tag> &tags) const;
|
|
||||||
bool match(int zoom, const QVector<MapData::Tag> &tags) const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum Type {
|
enum Type {
|
||||||
@ -109,8 +106,12 @@ public:
|
|||||||
if (!filter.isTautology())
|
if (!filter.isTautology())
|
||||||
_filters.append(filter);
|
_filters.append(filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool match(int zoom, Type type, Closed closed,
|
bool match(int zoom, Type type, Closed closed,
|
||||||
const QVector<MapData::Tag> &tags) const;
|
const QVector<MapData::Tag> &tags) const;
|
||||||
|
bool match(int zoom, bool closed,
|
||||||
|
const QVector<MapData::Tag> &tags) const;
|
||||||
|
bool match(int zoom, const QVector<MapData::Tag> &tags) const;
|
||||||
|
|
||||||
friend class Style;
|
friend class Style;
|
||||||
|
|
||||||
@ -266,9 +267,9 @@ public:
|
|||||||
QList<const CircleRender *> circles(int zoom,
|
QList<const CircleRender *> circles(int zoom,
|
||||||
const QVector<MapData::Tag> &tags) const;
|
const QVector<MapData::Tag> &tags) const;
|
||||||
QList<const TextRender*> pathLabels(int zoom) const;
|
QList<const TextRender*> pathLabels(int zoom) const;
|
||||||
QList<const TextRender*> pointLabels(int zoom) const;
|
QList<const TextRender*> labels(int zoom) const;
|
||||||
QList<const TextRender*> areaLabels(int zoom) const;
|
QList<const TextRender*> areaLabels(int zoom) const;
|
||||||
QList<const Symbol*> pointSymbols(int zoom) const;
|
QList<const Symbol*> symbols(int zoom) const;
|
||||||
QList<const Symbol*> areaSymbols(int zoom) const;
|
QList<const Symbol*> areaSymbols(int zoom) const;
|
||||||
QList<const Symbol*> lineSymbols(int zoom) const;
|
QList<const Symbol*> lineSymbols(int zoom) const;
|
||||||
const HillShadingRender *hillShading(int zoom) const;
|
const HillShadingRender *hillShading(int zoom) const;
|
||||||
|
Loading…
Reference in New Issue
Block a user