mirror of
https://github.com/tumic0/GPXSee.git
synced 2024-11-28 05:34:47 +01:00
Redesigned IMG caching
(Cache encoded data rather than raw data)
This commit is contained in:
parent
df1be4aeb9
commit
325e83569c
@ -4,23 +4,34 @@
|
||||
#include "vectortile.h"
|
||||
#include "img.h"
|
||||
|
||||
|
||||
#define CACHE_SIZE 8388608 /* 8MB */
|
||||
#define CACHED_SUBDIVS_COUNT 2048 // ~32MB
|
||||
|
||||
typedef QMap<QString, VectorTile*> TileMap;
|
||||
|
||||
struct CTX
|
||||
struct PolyCTX
|
||||
{
|
||||
CTX(const RectC &rect, int bits, QList<IMG::Poly> *polygons,
|
||||
QList<IMG::Poly> *lines, QList<IMG::Point> *points)
|
||||
PolyCTX(const RectC &rect, int bits, QList<IMG::Poly> *polygons,
|
||||
QList<IMG::Poly> *lines, QCache<const SubDiv*, IMG::Polys> *polyCache)
|
||||
: rect(rect), bits(bits), polygons(polygons), lines(lines),
|
||||
points(points) {}
|
||||
polyCache(polyCache) {}
|
||||
|
||||
const RectC ▭
|
||||
int bits;
|
||||
QList<IMG::Poly> *polygons;
|
||||
QList<IMG::Poly> *lines;
|
||||
QCache<const SubDiv*, IMG::Polys> *polyCache;
|
||||
};
|
||||
|
||||
struct PointCTX
|
||||
{
|
||||
PointCTX(const RectC &rect, int bits, QList<IMG::Point> *points,
|
||||
QCache<const SubDiv*, QList<IMG::Point> > *pointCache)
|
||||
: rect(rect), bits(bits), points(points), pointCache(pointCache) {}
|
||||
|
||||
const RectC ▭
|
||||
int bits;
|
||||
QList<IMG::Point> *points;
|
||||
QCache<const SubDiv*, QList<IMG::Point> > *pointCache;
|
||||
};
|
||||
|
||||
static SubFile::Type tileType(const char str[3])
|
||||
@ -78,8 +89,9 @@ IMG::IMG(const QString &fileName)
|
||||
QByteArray nba(QByteArray(d1, sizeof(d1)) + QByteArray(d2, sizeof(d2)));
|
||||
_name = QString::fromLatin1(nba.constData(), nba.size()-1).trimmed();
|
||||
_blockSize = 1 << (e1 + e2);
|
||||
_blockCache.setMaxCost(CACHE_SIZE / _blockSize);
|
||||
|
||||
_polyCache.setMaxCost(CACHED_SUBDIVS_COUNT);
|
||||
_pointCache.setMaxCost(CACHED_SUBDIVS_COUNT);
|
||||
|
||||
// Read the FAT table
|
||||
quint8 flag;
|
||||
@ -214,20 +226,28 @@ void IMG::clear()
|
||||
delete _style;
|
||||
_style = 0;
|
||||
|
||||
_blockCache.clear();
|
||||
_polyCache.clear();
|
||||
_pointCache.clear();
|
||||
}
|
||||
|
||||
static bool cb(VectorTile *tile, void *context)
|
||||
static bool polyCb(VectorTile *tile, void *context)
|
||||
{
|
||||
CTX *ctx = (CTX*)context;
|
||||
tile->objects(ctx->rect, ctx->bits, ctx->polygons, ctx->lines, ctx->points);
|
||||
PolyCTX *ctx = (PolyCTX*)context;
|
||||
tile->polys(ctx->rect, ctx->bits, ctx->polygons, ctx->lines, ctx->polyCache);
|
||||
return true;
|
||||
}
|
||||
|
||||
void IMG::objects(const RectC &rect, int bits, QList<Poly> *polygons,
|
||||
QList<Poly> *lines, QList<Point> *points)
|
||||
static bool pointCb(VectorTile *tile, void *context)
|
||||
{
|
||||
CTX ctx(rect, bits, polygons, lines, points);
|
||||
PointCTX *ctx = (PointCTX*)context;
|
||||
tile->points(ctx->rect, ctx->bits, ctx->points, ctx->pointCache);
|
||||
return true;
|
||||
}
|
||||
|
||||
void IMG::polys(const RectC &rect, int bits, QList<Poly> *polygons,
|
||||
QList<Poly> *lines)
|
||||
{
|
||||
PolyCTX ctx(rect, bits, polygons, lines, &_polyCache);
|
||||
double min[2], max[2];
|
||||
|
||||
min[0] = rect.left();
|
||||
@ -235,7 +255,20 @@ void IMG::objects(const RectC &rect, int bits, QList<Poly> *polygons,
|
||||
max[0] = rect.right();
|
||||
max[1] = rect.top();
|
||||
|
||||
_tileTree.Search(min, max, cb, &ctx);
|
||||
_tileTree.Search(min, max, polyCb, &ctx);
|
||||
}
|
||||
|
||||
void IMG::points(const RectC &rect, int bits, QList<Point> *points)
|
||||
{
|
||||
PointCTX ctx(rect, bits, points, &_pointCache);
|
||||
double min[2], max[2];
|
||||
|
||||
min[0] = rect.left();
|
||||
min[1] = rect.bottom();
|
||||
max[0] = rect.right();
|
||||
max[1] = rect.top();
|
||||
|
||||
_tileTree.Search(min, max, pointCb, &ctx);
|
||||
}
|
||||
|
||||
qint64 IMG::read(char *data, qint64 maxSize)
|
||||
@ -261,16 +294,11 @@ template<class T> bool IMG::readValue(T &val)
|
||||
|
||||
bool IMG::readBlock(int blockNum, QByteArray &data)
|
||||
{
|
||||
QByteArray *block = _blockCache[blockNum];
|
||||
if (!block) {
|
||||
if (!_file.seek((qint64)blockNum * (qint64)_blockSize))
|
||||
return false;
|
||||
data.resize(_blockSize);
|
||||
if (read(data.data(), _blockSize) < _blockSize)
|
||||
return false;
|
||||
_blockCache.insert(blockNum, new QByteArray(data));
|
||||
} else
|
||||
data = *block;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
class VectorTile;
|
||||
class SubFile;
|
||||
class SubDiv;
|
||||
|
||||
class IMG
|
||||
{
|
||||
@ -24,6 +25,7 @@ public:
|
||||
QVector<QPointF> points;
|
||||
Label label;
|
||||
quint32 type;
|
||||
RectC boundingRect;
|
||||
|
||||
bool operator<(const Poly &other) const
|
||||
{return type > other.type;}
|
||||
@ -42,6 +44,14 @@ public:
|
||||
{return id < other.id;}
|
||||
};
|
||||
|
||||
struct Polys {
|
||||
Polys() {}
|
||||
Polys(const QList<Poly> &polygons, const QList<Poly> &lines)
|
||||
: polygons(polygons), lines(lines) {}
|
||||
|
||||
QList<Poly> polygons;
|
||||
QList<Poly> lines;
|
||||
};
|
||||
|
||||
IMG(const QString &fileName);
|
||||
~IMG();
|
||||
@ -53,8 +63,9 @@ public:
|
||||
const QString &name() const {return _name;}
|
||||
const RectC &bounds() const {return _bounds;}
|
||||
|
||||
void objects(const RectC &rect, int bits, QList<Poly> *polygons,
|
||||
QList<Poly> *lines, QList<Point> *points);
|
||||
void polys(const RectC &rect, int bits, QList<Poly> *polygons,
|
||||
QList<Poly> *lines);
|
||||
void points(const RectC &rect, int bits, QList<Point> *points);
|
||||
const Style *style() const {return _style;}
|
||||
|
||||
bool isValid() const {return _valid;}
|
||||
@ -73,7 +84,6 @@ private:
|
||||
QFile _file;
|
||||
quint8 _key;
|
||||
int _blockSize;
|
||||
QCache<int, QByteArray> _blockCache;
|
||||
|
||||
QString _name;
|
||||
RectC _bounds;
|
||||
@ -81,6 +91,9 @@ private:
|
||||
SubFile *_typ;
|
||||
Style *_style;
|
||||
|
||||
QCache<const SubDiv*, Polys> _polyCache;
|
||||
QCache<const SubDiv*, QList<Point> > _pointCache;
|
||||
|
||||
bool _valid;
|
||||
QString _errorString;
|
||||
};
|
||||
|
@ -39,7 +39,7 @@ bool RGNFile::skipClassFields(Handle &hdl) const
|
||||
}
|
||||
|
||||
bool RGNFile::skipLclFields(Handle &hdl, const quint32 flags[3],
|
||||
Segment::Type type) const
|
||||
SegmentType type) const
|
||||
{
|
||||
quint32 bitfield = 0xFFFFFFFF;
|
||||
|
||||
@ -53,7 +53,7 @@ bool RGNFile::skipLclFields(Handle &hdl, const quint32 flags[3],
|
||||
quint32 m = flags[(i >> 4) + 1] >> ((i * 2) & 0x1e) & 3;
|
||||
switch (i) {
|
||||
case 5:
|
||||
if (m == 1 && type == Segment::Point) {
|
||||
if (m == 1 && type == Point) {
|
||||
quint16 u16;
|
||||
if (!readUInt16(hdl, u16))
|
||||
return false;
|
||||
@ -116,10 +116,15 @@ bool RGNFile::init(Handle &hdl)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RGNFile::polyObjects(const RectC &rect, Handle &hdl, const SubDiv *subdiv,
|
||||
const Segment &segment, LBLFile *lbl, Handle &lblHdl, NETFile *net,
|
||||
bool RGNFile::polyObjects(Handle &hdl, const SubDiv *subdiv,
|
||||
SegmentType segmentType, LBLFile *lbl, Handle &lblHdl, NETFile *net,
|
||||
Handle &netHdl, QList<IMG::Poly> *polys) const
|
||||
{
|
||||
const SubDiv::Segment &segment = (segmentType == Line)
|
||||
? subdiv->lines() : subdiv->polygons();
|
||||
|
||||
if (!segment.isValid())
|
||||
return true;
|
||||
if (!seek(hdl, segment.start()))
|
||||
return false;
|
||||
|
||||
@ -145,14 +150,14 @@ bool RGNFile::polyObjects(const RectC &rect, Handle &hdl, const SubDiv *subdiv,
|
||||
if (!readUInt8(hdl, bitstreamInfo))
|
||||
return false;
|
||||
|
||||
poly.type = (segment.type() == Segment::Polygon)
|
||||
poly.type = (segmentType == Polygon)
|
||||
? ((quint32)(type & 0x7F)) << 8 : ((quint32)(type & 0x3F)) << 8;
|
||||
|
||||
|
||||
QPoint pos(subdiv->lon() + ((qint32)lon<<(24-subdiv->bits())),
|
||||
subdiv->lat() + ((qint32)lat<<(24-subdiv->bits())));
|
||||
Coordinates c(toWGS24(pos.x()), toWGS24(pos.y()));
|
||||
RectC br(c, c);
|
||||
poly.boundingRect = RectC(c, c);
|
||||
poly.points.append(QPointF(c.lon(), c.lat()));
|
||||
|
||||
qint32 lonDelta, latDelta;
|
||||
@ -164,14 +169,11 @@ bool RGNFile::polyObjects(const RectC &rect, Handle &hdl, const SubDiv *subdiv,
|
||||
|
||||
Coordinates c(toWGS24(pos.x()), toWGS24(pos.y()));
|
||||
poly.points.append(QPointF(c.lon(), c.lat()));
|
||||
br = br.united(c);
|
||||
poly.boundingRect = poly.boundingRect.united(c);
|
||||
}
|
||||
if (!(stream.atEnd() && stream.flush()))
|
||||
return false;
|
||||
|
||||
if (!rect.intersects(br))
|
||||
continue;
|
||||
|
||||
if (lbl && (labelPtr & 0x3FFFFF)) {
|
||||
if (labelPtr & 0x800000) {
|
||||
quint32 lblOff;
|
||||
@ -188,22 +190,25 @@ bool RGNFile::polyObjects(const RectC &rect, Handle &hdl, const SubDiv *subdiv,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RGNFile::extPolyObjects(const RectC &rect, Handle &hdl,
|
||||
const SubDiv *subdiv, quint32 shift, const Segment &segment, LBLFile *lbl,
|
||||
Handle &lblHdl, QList<IMG::Poly> *polys, bool line) const
|
||||
bool RGNFile::extPolyObjects(Handle &hdl, const SubDiv *subdiv, quint32 shift,
|
||||
SegmentType segmentType, LBLFile *lbl, Handle &lblHdl,
|
||||
QList<IMG::Poly> *polys) const
|
||||
{
|
||||
quint32 labelPtr, len;
|
||||
quint8 type, subtype;
|
||||
qint16 lon, lat;
|
||||
const SubDiv::Segment &segment = (segmentType == Line)
|
||||
? subdiv->extLines() : subdiv->extPolygons();
|
||||
|
||||
|
||||
if (!segment.isValid())
|
||||
return true;
|
||||
if (!seek(hdl, segment.start()))
|
||||
return false;
|
||||
|
||||
while (hdl.pos < (int)segment.end()) {
|
||||
IMG::Poly poly;
|
||||
QPoint pos;
|
||||
RectC br;
|
||||
|
||||
if (!(readUInt8(hdl, type) && readUInt8(hdl, subtype)
|
||||
&& readInt16(hdl, lon) && readInt16(hdl, lat)
|
||||
@ -218,7 +223,8 @@ bool RGNFile::extPolyObjects(const RectC &rect, Handle &hdl,
|
||||
(subdiv->lat()<<8) + ((qint32)lat<<(32-subdiv->bits())));
|
||||
|
||||
qint32 lonDelta, latDelta;
|
||||
HuffmanStream stream(*this, hdl, len, _huffmanTable, line);
|
||||
HuffmanStream stream(*this, hdl, len, _huffmanTable,
|
||||
segmentType == Line);
|
||||
|
||||
if (shift) {
|
||||
if (!stream.readOffset(lonDelta, latDelta))
|
||||
@ -227,7 +233,7 @@ bool RGNFile::extPolyObjects(const RectC &rect, Handle &hdl,
|
||||
pos.y() | latDelta<<(32-subdiv->bits()-shift));
|
||||
}
|
||||
Coordinates c(toWGS32(pos.x()), toWGS32(pos.y()));
|
||||
br = RectC(c, c);
|
||||
poly.boundingRect = RectC(c, c);
|
||||
poly.points.append(QPointF(c.lon(), c.lat()));
|
||||
|
||||
while (stream.readNext(lonDelta, latDelta)) {
|
||||
@ -236,7 +242,7 @@ bool RGNFile::extPolyObjects(const RectC &rect, Handle &hdl,
|
||||
|
||||
Coordinates c(toWGS32(pos.x()), toWGS32(pos.y()));
|
||||
poly.points.append(QPointF(c.lon(), c.lat()));
|
||||
br = br.united(c);
|
||||
poly.boundingRect = poly.boundingRect.united(c);
|
||||
}
|
||||
|
||||
if (!(stream.atEnd() && stream.flush()))
|
||||
@ -245,7 +251,7 @@ bool RGNFile::extPolyObjects(const RectC &rect, Handle &hdl,
|
||||
pos = QPoint(subdiv->lon() + ((qint32)lon<<(24-subdiv->bits())),
|
||||
subdiv->lat() + ((qint32)lat<<(24-subdiv->bits())));
|
||||
Coordinates c(toWGS24(pos.x()), toWGS24(pos.y()));
|
||||
br = RectC(c, c);
|
||||
poly.boundingRect = RectC(c, c);
|
||||
poly.points.append(QPointF(c.lon(), c.lat()));
|
||||
|
||||
quint8 bitstreamInfo;
|
||||
@ -261,7 +267,7 @@ bool RGNFile::extPolyObjects(const RectC &rect, Handle &hdl,
|
||||
|
||||
Coordinates c(toWGS24(pos.x()), toWGS24(pos.y()));
|
||||
poly.points.append(QPointF(c.lon(), c.lat()));
|
||||
br = br.united(c);
|
||||
poly.boundingRect = poly.boundingRect.united(c);
|
||||
}
|
||||
if (!(stream.atEnd() && stream.flush()))
|
||||
return false;
|
||||
@ -271,13 +277,10 @@ bool RGNFile::extPolyObjects(const RectC &rect, Handle &hdl,
|
||||
return false;
|
||||
if (subtype & 0x80 && !skipClassFields(hdl))
|
||||
return false;
|
||||
if (subtype & 0x40 && !skipLclFields(hdl, line ? _linesFlags
|
||||
: _polygonsFlags, segment.type()))
|
||||
if (subtype & 0x40 && !skipLclFields(hdl, segmentType == Line
|
||||
? _linesFlags : _polygonsFlags, segmentType))
|
||||
return false;
|
||||
|
||||
if (!rect.intersects(br))
|
||||
continue;
|
||||
|
||||
if (lbl && (labelPtr & 0x3FFFFF))
|
||||
poly.label = lbl->label(lblHdl, labelPtr & 0x3FFFFF);
|
||||
|
||||
@ -287,14 +290,18 @@ bool RGNFile::extPolyObjects(const RectC &rect, Handle &hdl,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RGNFile::pointObjects(const RectC &rect, Handle &hdl, const SubDiv *subdiv,
|
||||
const Segment &segment, LBLFile *lbl, Handle &lblHdl,
|
||||
bool RGNFile::pointObjects(Handle &hdl, const SubDiv *subdiv,
|
||||
SegmentType segmentType, LBLFile *lbl, Handle &lblHdl,
|
||||
QList<IMG::Point> *points) const
|
||||
{
|
||||
quint8 type, subtype;
|
||||
qint16 lon, lat;
|
||||
quint32 labelPtr;
|
||||
const SubDiv::Segment &segment = (segmentType == IndexedPoint)
|
||||
? subdiv->idxPoints() : subdiv->points();
|
||||
|
||||
if (!segment.isValid())
|
||||
return true;
|
||||
if (!seek(hdl, segment.start()))
|
||||
return false;
|
||||
|
||||
@ -317,9 +324,6 @@ bool RGNFile::pointObjects(const RectC &rect, Handle &hdl, const SubDiv *subdiv,
|
||||
point.coordinates = Coordinates(toWGS24(subdiv->lon() + lonOffset),
|
||||
toWGS24(subdiv->lat() + latOffset));
|
||||
|
||||
if (!rect.contains(point.coordinates))
|
||||
continue;
|
||||
|
||||
point.poi = labelPtr & 0x400000;
|
||||
if (lbl && (labelPtr & 0x3FFFFF)) {
|
||||
point.label = lbl->label(lblHdl, labelPtr & 0x3FFFFF, point.poi);
|
||||
@ -333,14 +337,17 @@ bool RGNFile::pointObjects(const RectC &rect, Handle &hdl, const SubDiv *subdiv,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RGNFile::extPointObjects(const RectC &rect, Handle &hdl,
|
||||
const SubDiv *subdiv, const Segment &segment, LBLFile *lbl,
|
||||
bool RGNFile::extPointObjects(Handle &hdl, const SubDiv *subdiv, LBLFile *lbl,
|
||||
Handle &lblHdl, QList<IMG::Point> *points) const
|
||||
{
|
||||
quint8 type, subtype;
|
||||
qint16 lon, lat;
|
||||
quint32 labelPtr;
|
||||
const SubDiv::Segment &segment = subdiv->extPoints();
|
||||
|
||||
|
||||
if (!segment.isValid())
|
||||
return true;
|
||||
if (!seek(hdl, segment.start()))
|
||||
return false;
|
||||
|
||||
@ -363,10 +370,12 @@ bool RGNFile::extPointObjects(const RectC &rect, Handle &hdl,
|
||||
return false;
|
||||
if (subtype & 0x80 && !skipClassFields(hdl))
|
||||
return false;
|
||||
if (subtype & 0x40 && !skipLclFields(hdl, _pointsFlags, segment.type()))
|
||||
if (subtype & 0x40 && !skipLclFields(hdl, _pointsFlags, Point))
|
||||
return false;
|
||||
|
||||
if (!rect.contains(point.coordinates))
|
||||
// Discard NT points breaking style draw order logic (and causing huge
|
||||
// performance drawback)
|
||||
if (point.type == 0x11400)
|
||||
continue;
|
||||
|
||||
point.poi = labelPtr & 0x400000;
|
||||
@ -382,85 +391,13 @@ bool RGNFile::extPointObjects(const RectC &rect, Handle &hdl,
|
||||
return true;
|
||||
}
|
||||
|
||||
void RGNFile::objects(const RectC &rect, const SubDiv *subdiv,
|
||||
LBLFile *lbl, NETFile *net, QList<IMG::Poly> *polygons,
|
||||
QList<IMG::Poly> *lines, QList<IMG::Point> *points)
|
||||
QMap<RGNFile::SegmentType, SubDiv::Segment> RGNFile::segments(Handle &hdl,
|
||||
SubDiv *subdiv) const
|
||||
{
|
||||
Handle rgnHdl, lblHdl, netHdl;
|
||||
QMap<SegmentType, SubDiv::Segment> ret;
|
||||
|
||||
if (!_init && !init(rgnHdl))
|
||||
return;
|
||||
|
||||
QVector<Segment> seg(segments(rgnHdl, subdiv));
|
||||
|
||||
for (int i = 0; i < seg.size(); i++) {
|
||||
const Segment &segment = seg.at(i);
|
||||
|
||||
if (segment.start() == segment.end())
|
||||
continue;
|
||||
|
||||
switch (segment.type()) {
|
||||
case Segment::Point:
|
||||
case Segment::IndexedPoint:
|
||||
if (points)
|
||||
pointObjects(rect, rgnHdl, subdiv, segment, lbl, lblHdl,
|
||||
points);
|
||||
break;
|
||||
case Segment::Line:
|
||||
if (lines)
|
||||
polyObjects(rect, rgnHdl, subdiv, segment, lbl, lblHdl, net,
|
||||
netHdl, lines);
|
||||
break;
|
||||
case Segment::Polygon:
|
||||
if (polygons)
|
||||
polyObjects(rect, rgnHdl, subdiv, segment, lbl, lblHdl, net,
|
||||
netHdl, polygons);
|
||||
break;
|
||||
case Segment::RoadReference:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RGNFile::extObjects(const RectC &rect, const SubDiv *subdiv, quint32 shift,
|
||||
LBLFile *lbl, QList<IMG::Poly> *polygons, QList<IMG::Poly> *lines,
|
||||
QList<IMG::Point> *points)
|
||||
{
|
||||
Handle rgnHdl, lblHdl;
|
||||
|
||||
if (!_init && !init(rgnHdl))
|
||||
return;
|
||||
if (polygons && subdiv->polygonsOffset() != subdiv->polygonsEnd()) {
|
||||
quint32 start = _polygonsOffset + subdiv->polygonsOffset();
|
||||
quint32 end = subdiv->polygonsEnd()
|
||||
? _polygonsOffset + subdiv->polygonsEnd()
|
||||
: _polygonsOffset + _polygonsSize;
|
||||
extPolyObjects(rect, rgnHdl, subdiv, shift, Segment(start, end,
|
||||
Segment::Polygon), lbl, lblHdl, polygons, false);
|
||||
}
|
||||
if (lines && subdiv->linesOffset() != subdiv->linesEnd()) {
|
||||
quint32 start = _linesOffset + subdiv->linesOffset();
|
||||
quint32 end = subdiv->linesEnd()
|
||||
? _linesOffset + subdiv->linesEnd()
|
||||
: _linesOffset + _linesSize;
|
||||
extPolyObjects(rect, rgnHdl, subdiv, shift, Segment(start, end,
|
||||
Segment::Line), lbl, lblHdl, lines, true);
|
||||
}
|
||||
if (points && subdiv->pointsOffset() != subdiv->pointsEnd()) {
|
||||
quint32 start = _pointsOffset + subdiv->pointsOffset();
|
||||
quint32 end = subdiv->pointsEnd()
|
||||
? _pointsOffset + subdiv->pointsEnd()
|
||||
: _pointsOffset + _pointsSize;
|
||||
extPointObjects(rect, rgnHdl, subdiv, Segment(start, end,
|
||||
Segment::Point), lbl, lblHdl, points);
|
||||
}
|
||||
}
|
||||
|
||||
QVector<RGNFile::Segment> RGNFile::segments(Handle &hdl, const SubDiv *subdiv)
|
||||
const
|
||||
{
|
||||
if (subdiv->offset() == subdiv->end() || !(subdiv->objects() & 0x1F))
|
||||
return QVector<Segment>();
|
||||
return ret;
|
||||
|
||||
quint32 offset = _offset + subdiv->offset();
|
||||
|
||||
@ -470,57 +407,66 @@ QVector<RGNFile::Segment> RGNFile::segments(Handle &hdl, const SubDiv *subdiv)
|
||||
no++;
|
||||
|
||||
if (!seek(hdl, offset))
|
||||
return QVector<Segment>();
|
||||
return ret;
|
||||
|
||||
QVector<Segment> ret;
|
||||
quint32 start = offset + 2 * (no - 1);
|
||||
quint32 ls = 0;
|
||||
SegmentType lt = (SegmentType)0;
|
||||
quint16 po;
|
||||
int cnt = 0;
|
||||
|
||||
for (quint16 mask = 0x1; mask <= 0x10; mask <<= 1) {
|
||||
if (subdiv->objects() & mask) {
|
||||
if (cnt) {
|
||||
if (!readUInt16(hdl, po))
|
||||
return QVector<Segment>();
|
||||
if (!readUInt16(hdl, po) || !po)
|
||||
return QMap<RGNFile::SegmentType, SubDiv::Segment>();
|
||||
start = offset + po;
|
||||
}
|
||||
if (!ret.isEmpty())
|
||||
ret.last().setEnd(start);
|
||||
ret.append(Segment(start, (Segment::Type)mask));
|
||||
if (ls)
|
||||
ret.insert(lt, SubDiv::Segment(ls, start));
|
||||
|
||||
lt = (SegmentType)mask;
|
||||
ls = start;
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
ret.last().setEnd(subdiv->end() ? _offset + subdiv->end() : _offset + _size);
|
||||
ret.insert(lt, SubDiv::Segment(ls, subdiv->end()
|
||||
? _offset + subdiv->end() : _offset + _size));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
QDebug operator<<(QDebug dbg, const RGNFile::Segment &segment)
|
||||
bool RGNFile::subdivInit(Handle &hdl, SubDiv *subdiv) const
|
||||
{
|
||||
QString type;
|
||||
switch (segment.type()) {
|
||||
case RGNFile::Segment::Point:
|
||||
type = "Point";
|
||||
break;
|
||||
case RGNFile::Segment::IndexedPoint:
|
||||
type = "IndexedPoint";
|
||||
break;
|
||||
case RGNFile::Segment::Line:
|
||||
type = "Line";
|
||||
break;
|
||||
case RGNFile::Segment::Polygon:
|
||||
type = "Polygon";
|
||||
break;
|
||||
case RGNFile::Segment::RoadReference:
|
||||
type = "RoadReference";
|
||||
break;
|
||||
QMap<RGNFile::SegmentType, SubDiv::Segment> seg(segments(hdl, subdiv));
|
||||
SubDiv::Segment extPoints, extLines, extPolygons;
|
||||
|
||||
if (subdiv->extPointsOffset() != subdiv->extPointsEnd()) {
|
||||
quint32 start = _pointsOffset + subdiv->extPointsOffset();
|
||||
quint32 end = subdiv->extPointsEnd()
|
||||
? _pointsOffset + subdiv->extPointsEnd()
|
||||
: _pointsOffset + _pointsSize;
|
||||
extPoints = SubDiv::Segment(start, end);
|
||||
}
|
||||
if (subdiv->extPolygonsOffset() != subdiv->extPolygonsEnd()) {
|
||||
quint32 start = _polygonsOffset + subdiv->extPolygonsOffset();
|
||||
quint32 end = subdiv->extPolygonsEnd()
|
||||
? _polygonsOffset + subdiv->extPolygonsEnd()
|
||||
: _polygonsOffset + _polygonsSize;
|
||||
extPolygons = SubDiv::Segment(start, end);
|
||||
}
|
||||
if (subdiv->extLinesOffset() != subdiv->extLinesEnd()) {
|
||||
quint32 start = _linesOffset + subdiv->extLinesOffset();
|
||||
quint32 end = subdiv->extLinesEnd()
|
||||
? _linesOffset + subdiv->extLinesEnd()
|
||||
: _linesOffset + _linesSize;
|
||||
extLines = SubDiv::Segment(start, end);
|
||||
}
|
||||
|
||||
dbg.nospace() << "Segment(" << segment.start() << ", " << segment.end()
|
||||
- segment.start() << ", " << type << ")";
|
||||
subdiv->init(seg.value(Point), seg.value(IndexedPoint), seg.value(Line),
|
||||
seg.value(Polygon), seg.value(RoadReference), extPoints, extLines,
|
||||
extPolygons);
|
||||
|
||||
return dbg.space();
|
||||
return true;
|
||||
}
|
||||
#endif // QT_NO_DEBUG
|
||||
|
@ -12,6 +12,14 @@ class NETFile;
|
||||
class RGNFile : public SubFile
|
||||
{
|
||||
public:
|
||||
enum SegmentType {
|
||||
Point = 0x1,
|
||||
IndexedPoint = 0x2,
|
||||
Line = 0x4,
|
||||
Polygon = 0x8,
|
||||
RoadReference = 0x10
|
||||
};
|
||||
|
||||
RGNFile(IMG *img)
|
||||
: SubFile(img), _offset(0), _size(0), _polygonsOffset(0),
|
||||
_polygonsSize(0), _linesOffset(0), _linesSize(0), _pointsOffset(0),
|
||||
@ -21,65 +29,29 @@ public:
|
||||
_linesSize(0), _pointsOffset(0), _pointsSize(0), _init(false)
|
||||
{clearFlags();}
|
||||
|
||||
void objects(const RectC &rect, const SubDiv *subdiv,
|
||||
LBLFile *lbl, NETFile *net, QList<IMG::Poly> *polygons,
|
||||
QList<IMG::Poly> *lines, QList<IMG::Point> *points);
|
||||
void extObjects(const RectC &rect, const SubDiv *subdiv, quint32 shift,
|
||||
LBLFile *lbl, QList<IMG::Poly> *polygons, QList<IMG::Poly> *lines,
|
||||
QList<IMG::Point> *points);
|
||||
|
||||
private:
|
||||
class Segment {
|
||||
public:
|
||||
enum Type {
|
||||
Point = 0x1,
|
||||
IndexedPoint = 0x2,
|
||||
Line = 0x4,
|
||||
Polygon = 0x8,
|
||||
RoadReference = 0x10
|
||||
};
|
||||
|
||||
Segment() : _start(0), _end(0), _type(Point) {}
|
||||
Segment(quint32 start, Type type)
|
||||
: _start(start), _end(0), _type(type) {}
|
||||
Segment(quint32 start, quint32 end, Type type)
|
||||
: _start(start), _end(end), _type(type) {}
|
||||
|
||||
void setEnd(quint32 end) {_end = end;}
|
||||
|
||||
quint32 start() const {return _start;}
|
||||
quint32 end() const {return _end;}
|
||||
Type type() const {return _type;}
|
||||
|
||||
private:
|
||||
quint32 _start;
|
||||
quint32 _end;
|
||||
Type _type;
|
||||
};
|
||||
|
||||
bool initialized() const {return _init;}
|
||||
bool init(Handle &hdl);
|
||||
|
||||
QVector<Segment> segments(Handle &hdl, const SubDiv *subdiv) const;
|
||||
bool polyObjects(const RectC &rect, Handle &hdl, const SubDiv *subdiv,
|
||||
const Segment &segment, LBLFile *lbl, Handle &lblHdl, NETFile *net,
|
||||
Handle &netHdl, QList<IMG::Poly> *polys) const;
|
||||
bool pointObjects(const RectC &rect, Handle &hdl, const SubDiv *subdiv,
|
||||
const Segment &segment, LBLFile *lbl, Handle &lblHdl,
|
||||
QList<IMG::Point> *points) const;
|
||||
bool extPolyObjects(const RectC &rect, Handle &hdl, const SubDiv *subdiv,
|
||||
quint32 shift, const Segment &segment, LBLFile *lbl, Handle &lblHdl,
|
||||
QList<IMG::Poly> *polys, bool line) const;
|
||||
bool extPointObjects(const RectC &rect, Handle &hdl, const SubDiv *subdiv,
|
||||
const Segment &segment, LBLFile *lbl, Handle &lblHdl,
|
||||
QList<IMG::Point> *points) const;
|
||||
bool polyObjects(Handle &hdl, const SubDiv *subdiv, SegmentType segmentType,
|
||||
LBLFile *lbl, Handle &lblHdl, NETFile *net, Handle &netHdl,
|
||||
QList<IMG::Poly> *polys) const;
|
||||
bool pointObjects(Handle &hdl, const SubDiv *subdiv, SegmentType segmentType,
|
||||
LBLFile *lbl, Handle &lblHdl, QList<IMG::Point> *points) const;
|
||||
bool extPolyObjects(Handle &hdl, const SubDiv *subdiv, quint32 shift,
|
||||
SegmentType segmentType, LBLFile *lbl, Handle &lblHdl,
|
||||
QList<IMG::Poly> *polys) const;
|
||||
bool extPointObjects(Handle &hdl, const SubDiv *subdiv, LBLFile *lbl,
|
||||
Handle &lblHdl, QList<IMG::Point> *points) const;
|
||||
|
||||
bool subdivInit(Handle &hdl, SubDiv *subdiv) const;
|
||||
|
||||
private:
|
||||
QMap<SegmentType, SubDiv::Segment> segments(Handle &hdl, SubDiv *subdiv)
|
||||
const;
|
||||
void clearFlags();
|
||||
|
||||
bool skipClassFields(Handle &hdl) const;
|
||||
bool skipLclFields(Handle &hdl, const quint32 flags[3],
|
||||
Segment::Type type) const;
|
||||
|
||||
friend QDebug operator<<(QDebug dbg, const RGNFile::Segment &segment);
|
||||
bool skipLclFields(Handle &hdl, const quint32 flags[3], SegmentType type)
|
||||
const;
|
||||
|
||||
quint32 _offset;
|
||||
quint32 _size;
|
||||
@ -99,8 +71,4 @@ private:
|
||||
bool _init;
|
||||
};
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
QDebug operator<<(QDebug dbg, const RGNFile::Segment &segment);
|
||||
#endif // QT_NO_DEBUG
|
||||
|
||||
#endif // RGNFILE_H
|
||||
|
@ -939,9 +939,6 @@ Style::Style(SubFile *typ)
|
||||
|
||||
if (typ)
|
||||
parseTYPFile(typ);
|
||||
|
||||
// Override stuff breaking the style display logic
|
||||
_points[0x11400] = Point(None);
|
||||
}
|
||||
|
||||
const Style::Line &Style::line(quint32 type) const
|
||||
|
@ -7,55 +7,123 @@
|
||||
|
||||
class SubDiv {
|
||||
public:
|
||||
SubDiv(quint32 offset, qint32 lon, qint32 lat, int bits, quint8 objects)
|
||||
: _offset(offset), _end(0), _lon(lon), _lat(lat), _bits(bits),
|
||||
_objects(objects), _polygonsOffset(0), _polygonsEnd(0), _linesOffset(0),
|
||||
_linesEnd(0), _pointsOffset(0), _pointsEnd(0) {}
|
||||
void setEnd(quint32 end) {_end = end;}
|
||||
class Segment {
|
||||
public:
|
||||
Segment() : _start(0), _end(0) {}
|
||||
Segment(quint32 start, quint32 end) : _start(start), _end(end) {}
|
||||
|
||||
quint32 offset() const {return _offset;}
|
||||
bool isValid() const {return (_end > _start);}
|
||||
|
||||
quint32 start() const {return _start;}
|
||||
quint32 end() const {return _end;}
|
||||
|
||||
private:
|
||||
quint32 _start, _end;
|
||||
};
|
||||
|
||||
SubDiv(quint32 offset, qint32 lon, qint32 lat, int bits, quint8 objects)
|
||||
: _lon(lon), _lat(lat), _bits(bits), _init(false)
|
||||
{
|
||||
_tre.objects = objects;
|
||||
_tre.offset = offset;
|
||||
_tre.end = 0;
|
||||
|
||||
_tre.polygonsOffset = 0;
|
||||
_tre.polygonsEnd = 0;
|
||||
_tre.linesOffset = 0;
|
||||
_tre.linesEnd = 0;
|
||||
_tre.pointsOffset = 0;
|
||||
_tre.pointsEnd = 0;
|
||||
}
|
||||
void setEnd(quint32 end) {_tre.end = end;}
|
||||
void setExtOffsets(quint32 polygon, quint32 line, quint32 point)
|
||||
{
|
||||
_tre.polygonsOffset = polygon;
|
||||
_tre.linesOffset = line;
|
||||
_tre.pointsOffset = point;
|
||||
}
|
||||
void setExtEnds(quint32 polygon, quint32 line, quint32 point)
|
||||
{
|
||||
_tre.polygonsEnd = polygon;
|
||||
_tre.linesEnd = line;
|
||||
_tre.pointsEnd = point;
|
||||
}
|
||||
|
||||
void init(const Segment &points, const Segment &idxPoints,
|
||||
const Segment &lines, const Segment &polygons,
|
||||
const Segment &roadReferences, const Segment &extPoints,
|
||||
const Segment &extLines, const Segment &extPolygons)
|
||||
{
|
||||
_rgn.points = points;
|
||||
_rgn.idxPoints = idxPoints;
|
||||
_rgn.lines = lines;
|
||||
_rgn.polygons = polygons;
|
||||
_rgn.roadReferences = roadReferences;
|
||||
_rgn.extPoints = extPoints;
|
||||
_rgn.extLines = extLines;
|
||||
_rgn.extPolygons = extPolygons;
|
||||
_init = true;
|
||||
}
|
||||
bool initialized() const {return _init;}
|
||||
|
||||
qint32 lon() const {return _lon;}
|
||||
qint32 lat() const {return _lat;}
|
||||
quint8 bits() const {return _bits;}
|
||||
quint8 objects() const {return _objects;}
|
||||
|
||||
// Extended types objects (TRE7)
|
||||
void setExtOffsets(quint32 polygon, quint32 line, quint32 point)
|
||||
{_polygonsOffset = polygon; _linesOffset = line; _pointsOffset = point;}
|
||||
void setExtEnds(quint32 polygon, quint32 line, quint32 point)
|
||||
{_polygonsEnd = polygon; _linesEnd = line; _pointsEnd = point;}
|
||||
// Valid only after initialization
|
||||
const Segment &points() const {return _rgn.points;}
|
||||
const Segment &idxPoints() const {return _rgn.idxPoints;}
|
||||
const Segment &lines() const {return _rgn.lines;}
|
||||
const Segment &polygons() const {return _rgn.polygons;}
|
||||
const Segment &extPoints() const {return _rgn.extPoints;}
|
||||
const Segment &extLines() const {return _rgn.extLines;}
|
||||
const Segment &extPolygons() const {return _rgn.extPolygons;}
|
||||
|
||||
quint32 polygonsOffset() const {return _polygonsOffset;}
|
||||
quint32 polygonsEnd() const {return _polygonsEnd;}
|
||||
quint32 linesOffset() const {return _linesOffset;}
|
||||
quint32 linesEnd() const {return _linesEnd;}
|
||||
quint32 pointsOffset() const {return _pointsOffset;}
|
||||
quint32 pointsEnd() const {return _pointsEnd;}
|
||||
// Valid only until initialization
|
||||
quint8 objects() const {return _tre.objects;}
|
||||
quint32 offset() const {return _tre.offset;}
|
||||
quint32 end() const {return _tre.end;}
|
||||
quint32 extPolygonsOffset() const {return _tre.polygonsOffset;}
|
||||
quint32 extPolygonsEnd() const {return _tre.polygonsEnd;}
|
||||
quint32 extLinesOffset() const {return _tre.linesOffset;}
|
||||
quint32 extLinesEnd() const {return _tre.linesEnd;}
|
||||
quint32 extPointsOffset() const {return _tre.pointsOffset;}
|
||||
quint32 extPointsEnd() const {return _tre.pointsEnd;}
|
||||
|
||||
private:
|
||||
quint32 _offset;
|
||||
quint32 _end;
|
||||
struct TRE
|
||||
{
|
||||
quint8 objects;
|
||||
quint32 offset;
|
||||
quint32 end;
|
||||
|
||||
quint32 polygonsOffset;
|
||||
quint32 polygonsEnd;
|
||||
quint32 linesOffset;
|
||||
quint32 linesEnd;
|
||||
quint32 pointsOffset;
|
||||
quint32 pointsEnd;
|
||||
};
|
||||
|
||||
struct RGN
|
||||
{
|
||||
Segment points;
|
||||
Segment idxPoints;
|
||||
Segment lines;
|
||||
Segment polygons;
|
||||
Segment roadReferences;
|
||||
Segment extPoints;
|
||||
Segment extLines;
|
||||
Segment extPolygons;
|
||||
};
|
||||
|
||||
qint32 _lon, _lat;
|
||||
quint8 _bits;
|
||||
quint8 _objects;
|
||||
|
||||
quint32 _polygonsOffset;
|
||||
quint32 _polygonsEnd;
|
||||
quint32 _linesOffset;
|
||||
quint32 _linesEnd;
|
||||
quint32 _pointsOffset;
|
||||
quint32 _pointsEnd;
|
||||
bool _init;
|
||||
union {
|
||||
TRE _tre;
|
||||
RGN _rgn;
|
||||
};
|
||||
};
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
inline QDebug operator<<(QDebug dbg, const SubDiv &subdiv)
|
||||
{
|
||||
Coordinates c(toWGS24(subdiv.lon()), toWGS24(subdiv.lat()));
|
||||
dbg.nospace() << "SubDiv(" << c << ", " << subdiv.offset()
|
||||
<< ", " << subdiv.end() << ", " << subdiv.objects() << ")";
|
||||
return dbg.space();
|
||||
}
|
||||
#endif // QT_NO_DEBUG
|
||||
|
||||
#endif // SUBDIV_H
|
||||
|
@ -1,5 +1,23 @@
|
||||
#include "vectortile.h"
|
||||
|
||||
|
||||
static void copyPolys(const RectC &rect, QList<IMG::Poly> *src,
|
||||
QList<IMG::Poly> *dst)
|
||||
{
|
||||
for (int i = 0; i < src->size(); i++)
|
||||
if (rect.intersects(src->at(i).boundingRect))
|
||||
dst->append(src->at(i));
|
||||
}
|
||||
|
||||
static void copyPoints(const RectC &rect, QList<IMG::Point> *src,
|
||||
QList<IMG::Point> *dst)
|
||||
{
|
||||
for (int j = 0; j < src->size(); j++)
|
||||
if (rect.contains(src->at(j).coordinates))
|
||||
dst->append(src->at(j));
|
||||
}
|
||||
|
||||
|
||||
SubFile *VectorTile::file(SubFile::Type type)
|
||||
{
|
||||
switch (type) {
|
||||
@ -70,17 +88,75 @@ bool VectorTile::initGMP()
|
||||
return true;
|
||||
}
|
||||
|
||||
void VectorTile::objects(const RectC &rect, int bits,
|
||||
QList<IMG::Poly> *polygons, QList<IMG::Poly> *lines,
|
||||
QList<IMG::Point> *points) const
|
||||
void VectorTile::polys(const RectC &rect, int bits, QList<IMG::Poly> *polygons,
|
||||
QList<IMG::Poly> *lines, QCache<const SubDiv *, IMG::Polys> *polyCache)
|
||||
const
|
||||
{
|
||||
SubFile::Handle rgnHdl, lblHdl, netHdl;
|
||||
|
||||
if (!_rgn->initialized() && !_rgn->init(rgnHdl))
|
||||
return;
|
||||
|
||||
QList<SubDiv*> subdivs = _tre->subdivs(rect, bits);
|
||||
for (int i = 0; i < subdivs.size(); i++) {
|
||||
const SubDiv *subdiv = subdivs.at(i);
|
||||
quint32 shift = _tre->shift(subdiv->bits());
|
||||
SubDiv *subdiv = subdivs.at(i);
|
||||
|
||||
_rgn->objects(rect, subdiv, _lbl, _net, polygons, lines, points);
|
||||
_rgn->extObjects(rect, subdiv, shift, _lbl, polygons, lines, points);
|
||||
IMG::Polys *polys = polyCache->object(subdiv);
|
||||
if (!polys) {
|
||||
quint32 shift = _tre->shift(subdiv->bits());
|
||||
QList<IMG::Poly> p, l;
|
||||
|
||||
if (!subdiv->initialized() && !_rgn->subdivInit(rgnHdl, subdiv))
|
||||
continue;
|
||||
|
||||
_rgn->polyObjects(rgnHdl, subdiv, RGNFile::Polygon, _lbl, lblHdl,
|
||||
_net, netHdl, &p);
|
||||
_rgn->polyObjects(rgnHdl, subdiv, RGNFile::Line, _lbl, lblHdl,
|
||||
_net, netHdl, &l);
|
||||
_rgn->extPolyObjects(rgnHdl, subdiv, shift, RGNFile::Polygon, _lbl,
|
||||
lblHdl, &p);
|
||||
_rgn->extPolyObjects(rgnHdl, subdiv, shift, RGNFile::Line, _lbl,
|
||||
lblHdl, &l);
|
||||
|
||||
copyPolys(rect, &p, polygons);
|
||||
copyPolys(rect, &l, lines);
|
||||
polyCache->insert(subdiv, new IMG::Polys(p, l));
|
||||
} else {
|
||||
copyPolys(rect, &(polys->polygons), polygons);
|
||||
copyPolys(rect, &(polys->lines), lines);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VectorTile::points(const RectC &rect, int bits, QList<IMG::Point> *points,
|
||||
QCache<const SubDiv *, QList<IMG::Point> > *pointCache) const
|
||||
{
|
||||
SubFile::Handle rgnHdl, lblHdl;
|
||||
|
||||
if (!_rgn->initialized() && !_rgn->init(rgnHdl))
|
||||
return;
|
||||
|
||||
QList<SubDiv*> subdivs = _tre->subdivs(rect, bits);
|
||||
for (int i = 0; i < subdivs.size(); i++) {
|
||||
SubDiv *subdiv = subdivs.at(i);
|
||||
|
||||
QList<IMG::Point> *pl = pointCache->object(subdiv);
|
||||
if (!pl) {
|
||||
QList<IMG::Point> p;
|
||||
|
||||
if (!subdiv->initialized() && !_rgn->subdivInit(rgnHdl, subdiv))
|
||||
continue;
|
||||
|
||||
_rgn->pointObjects(rgnHdl, subdiv, RGNFile::Point, _lbl, lblHdl,
|
||||
&p);
|
||||
_rgn->pointObjects(rgnHdl, subdiv, RGNFile::IndexedPoint, _lbl,
|
||||
lblHdl, &p);
|
||||
_rgn->extPointObjects(rgnHdl, subdiv, _lbl, lblHdl, &p);
|
||||
|
||||
copyPoints(rect, &p, points);
|
||||
pointCache->insert(subdiv, new QList<IMG::Point>(p));
|
||||
} else
|
||||
copyPoints(rect, pl, points);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,8 +24,11 @@ public:
|
||||
SubFile *file(SubFile::Type type);
|
||||
SubFile *addFile(IMG *img, SubFile::Type type);
|
||||
|
||||
void objects(const RectC &rect, int bits, QList<IMG::Poly> *polygons,
|
||||
QList<IMG::Poly> *lines, QList<IMG::Point> *points) const;
|
||||
void polys(const RectC &rect, int bits, QList<IMG::Poly> *polygons,
|
||||
QList<IMG::Poly> *lines, QCache<const SubDiv *, IMG::Polys> *polyCache)
|
||||
const;
|
||||
void points(const RectC &rect, int bits, QList<IMG::Point> *points,
|
||||
QCache<const SubDiv*, QList<IMG::Point> > *pointCache) const;
|
||||
|
||||
static bool isTileFile(SubFile::Type type)
|
||||
{
|
||||
|
@ -322,7 +322,6 @@ Coordinates IMGMap::xy2ll(const QPointF &p)
|
||||
return _projection.xy2ll(_transform.img2proj(p));
|
||||
}
|
||||
|
||||
|
||||
void IMGMap::drawPolygons(QPainter *painter, const QList<IMG::Poly> &polygons)
|
||||
{
|
||||
for (int n = 0; n < _img.style()->drawOrder().size(); n++) {
|
||||
@ -585,13 +584,14 @@ void IMGMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
|
||||
|
||||
RectD polyRect(_transform.img2proj(ttl), _transform.img2proj(
|
||||
QPointF(ttl.x() + TILE_SIZE, ttl.y() + TILE_SIZE)));
|
||||
_img.objects(polyRect.toRectC(_projection, 4), _zoom,
|
||||
&(tile.polygons()), &(tile.lines()), 0);
|
||||
_img.polys(polyRect.toRectC(_projection, 4), _zoom,
|
||||
&(tile.polygons()), &(tile.lines()));
|
||||
|
||||
RectD pointRect(_transform.img2proj(QPointF(ttl.x() - TEXT_EXTENT,
|
||||
ttl.y() - TEXT_EXTENT)), _transform.img2proj(QPointF(ttl.x()
|
||||
+ TILE_SIZE + TEXT_EXTENT, ttl.y() + TILE_SIZE + TEXT_EXTENT)));
|
||||
_img.objects(pointRect.toRectC(_projection, 4), _zoom,
|
||||
0, 0, &(tile.points()));
|
||||
_img.points(pointRect.toRectC(_projection, 4), _zoom,
|
||||
&(tile.points()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user