2019-05-10 18:56:19 +02:00
|
|
|
#include "vectortile.h"
|
|
|
|
|
2020-02-07 22:10:06 +01:00
|
|
|
|
|
|
|
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));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-05-10 18:56:19 +02:00
|
|
|
SubFile *VectorTile::file(SubFile::Type type)
|
|
|
|
{
|
|
|
|
switch (type) {
|
|
|
|
case SubFile::TRE:
|
|
|
|
return _tre;
|
|
|
|
case SubFile::RGN:
|
|
|
|
return _rgn;
|
|
|
|
case SubFile::LBL:
|
|
|
|
return _lbl;
|
|
|
|
case SubFile::NET:
|
|
|
|
return _net;
|
2019-09-05 22:31:13 +02:00
|
|
|
case SubFile::GMP:
|
|
|
|
return _gmp;
|
2019-05-10 18:56:19 +02:00
|
|
|
default:
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-05 22:31:13 +02:00
|
|
|
SubFile *VectorTile::addFile(IMG *img, SubFile::Type type)
|
2019-05-10 18:56:19 +02:00
|
|
|
{
|
|
|
|
switch (type) {
|
|
|
|
case SubFile::TRE:
|
2019-09-05 22:31:13 +02:00
|
|
|
_tre = new TREFile(img);
|
2019-05-10 18:56:19 +02:00
|
|
|
return _tre;
|
|
|
|
case SubFile::RGN:
|
2019-09-05 22:31:13 +02:00
|
|
|
_rgn = new RGNFile(img);
|
2019-05-10 18:56:19 +02:00
|
|
|
return _rgn;
|
|
|
|
case SubFile::LBL:
|
2019-09-05 22:31:13 +02:00
|
|
|
_lbl = new LBLFile(img);
|
2019-05-10 18:56:19 +02:00
|
|
|
return _lbl;
|
|
|
|
case SubFile::NET:
|
2019-09-05 22:31:13 +02:00
|
|
|
_net = new NETFile(img);
|
2019-05-10 18:56:19 +02:00
|
|
|
return _net;
|
2019-09-05 22:31:13 +02:00
|
|
|
case SubFile::GMP:
|
|
|
|
_gmp = new SubFile(img);
|
|
|
|
return _gmp;
|
2019-05-10 18:56:19 +02:00
|
|
|
default:
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool VectorTile::init()
|
|
|
|
{
|
2019-09-05 22:31:13 +02:00
|
|
|
if (_gmp && !initGMP())
|
2019-05-10 18:56:19 +02:00
|
|
|
return false;
|
2019-09-05 22:31:13 +02:00
|
|
|
|
2019-09-10 19:45:06 +02:00
|
|
|
if (!(_tre && _tre->init() && _rgn))
|
2019-05-10 18:56:19 +02:00
|
|
|
return false;
|
2019-09-05 22:31:13 +02:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool VectorTile::initGMP()
|
|
|
|
{
|
|
|
|
SubFile::Handle hdl;
|
|
|
|
quint32 tre, rgn, lbl, net;
|
|
|
|
|
|
|
|
if (!(_gmp->seek(hdl, 0x19) && _gmp->readUInt32(hdl, tre)
|
|
|
|
&& _gmp->readUInt32(hdl, rgn) && _gmp->readUInt32(hdl, lbl)
|
|
|
|
&& _gmp->readUInt32(hdl, net)))
|
2019-05-10 18:56:19 +02:00
|
|
|
return false;
|
|
|
|
|
2019-09-05 22:31:13 +02:00
|
|
|
_tre = new TREFile(_gmp, tre);
|
|
|
|
_rgn = new RGNFile(_gmp, rgn);
|
|
|
|
_lbl = new LBLFile(_gmp, lbl);
|
|
|
|
_net = new NETFile(_gmp, net);
|
|
|
|
|
2019-05-10 18:56:19 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2020-02-07 22:10:06 +01:00
|
|
|
void VectorTile::polys(const RectC &rect, int bits, QList<IMG::Poly> *polygons,
|
|
|
|
QList<IMG::Poly> *lines, QCache<const SubDiv *, IMG::Polys> *polyCache)
|
|
|
|
const
|
2019-05-10 18:56:19 +02:00
|
|
|
{
|
2020-02-07 22:10:06 +01:00
|
|
|
SubFile::Handle rgnHdl, lblHdl, netHdl;
|
|
|
|
|
|
|
|
if (!_rgn->initialized() && !_rgn->init(rgnHdl))
|
|
|
|
return;
|
|
|
|
|
2019-05-10 18:56:19 +02:00
|
|
|
QList<SubDiv*> subdivs = _tre->subdivs(rect, bits);
|
|
|
|
for (int i = 0; i < subdivs.size(); i++) {
|
2020-02-07 22:10:06 +01:00
|
|
|
SubDiv *subdiv = subdivs.at(i);
|
|
|
|
|
|
|
|
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);
|
2020-01-21 21:50:13 +01:00
|
|
|
|
2020-02-07 22:10:06 +01:00
|
|
|
copyPoints(rect, &p, points);
|
|
|
|
pointCache->insert(subdiv, new QList<IMG::Point>(p));
|
|
|
|
} else
|
|
|
|
copyPoints(rect, pl, points);
|
2019-05-10 18:56:19 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef QT_NO_DEBUG
|
|
|
|
QDebug operator<<(QDebug dbg, const VectorTile &tile)
|
|
|
|
{
|
2020-01-19 13:23:20 +01:00
|
|
|
dbg.nospace() << "VectorTile(" << tile.bounds() <<")";
|
2019-05-10 18:56:19 +02:00
|
|
|
|
|
|
|
return dbg.space();
|
|
|
|
}
|
|
|
|
#endif // QT_NO_DEBUG
|