mirror of
https://github.com/tumic0/GPXSee.git
synced 2025-04-12 00:29:11 +02:00
163 lines
3.5 KiB
C++
163 lines
3.5 KiB
C++
#include <QFileInfo>
|
|
#include "common/programpaths.h"
|
|
#include "vectortile.h"
|
|
#include "style.h"
|
|
#include "mapdata.h"
|
|
|
|
|
|
using namespace IMG;
|
|
|
|
#define CACHED_SUBDIVS_COUNT 2048 // ~32MB for both caches together
|
|
#define CACHED_DEMTILES_COUNT 1024 // ~32MB
|
|
|
|
bool MapData::polyCb(VectorTile *tile, void *context)
|
|
{
|
|
PolyCTX *ctx = (PolyCTX*)context;
|
|
tile->polys(ctx->rect, ctx->zoom, ctx->polygons, ctx->lines,
|
|
ctx->cache, ctx->lock);
|
|
return true;
|
|
}
|
|
|
|
bool MapData::pointCb(VectorTile *tile, void *context)
|
|
{
|
|
PointCTX *ctx = (PointCTX*)context;
|
|
tile->points(ctx->rect, ctx->zoom, ctx->points, ctx->cache, ctx->lock);
|
|
return true;
|
|
}
|
|
|
|
bool MapData::elevationCb(VectorTile *tile, void *context)
|
|
{
|
|
ElevationCTX *ctx = (ElevationCTX*)context;
|
|
tile->elevations(ctx->rect, ctx->zoom, ctx->elevations, ctx->cache, ctx->lock);
|
|
return true;
|
|
}
|
|
|
|
MapData::MapData(const QString &fileName)
|
|
: _fileName(fileName), _typ(0), _style(0), _hasDEM(false), _valid(false)
|
|
{
|
|
_polyCache.setMaxCost(CACHED_SUBDIVS_COUNT);
|
|
_pointCache.setMaxCost(CACHED_SUBDIVS_COUNT);
|
|
_demCache.setMaxCost(CACHED_DEMTILES_COUNT);
|
|
}
|
|
|
|
MapData::~MapData()
|
|
{
|
|
TileTree::Iterator it;
|
|
for (_tileTree.GetFirst(it); !_tileTree.IsNull(it); _tileTree.GetNext(it))
|
|
delete _tileTree.GetAt(it);
|
|
|
|
delete _typ;
|
|
delete _style;
|
|
}
|
|
|
|
void MapData::polys(const RectC &rect, int bits, QList<Poly> *polygons,
|
|
QList<Poly> *lines)
|
|
{
|
|
PolyCTX ctx(rect, zoom(bits), polygons, lines, &_polyCache, &_lock);
|
|
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, polyCb, &ctx);
|
|
}
|
|
|
|
void MapData::points(const RectC &rect, int bits, QList<Point> *points)
|
|
{
|
|
PointCTX ctx(rect, zoom(bits), points, &_pointCache, &_lock);
|
|
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);
|
|
}
|
|
|
|
void MapData::elevations(const RectC &rect, int bits, QList<Elevation> *elevations)
|
|
{
|
|
ElevationCTX ctx(rect, zoom(bits), elevations, &_demCache, &_demLock);
|
|
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, elevationCb, &ctx);
|
|
}
|
|
|
|
void MapData::load(qreal ratio)
|
|
{
|
|
Q_ASSERT(!_style);
|
|
|
|
if (_typ)
|
|
_style = new Style(ratio, _typ);
|
|
else {
|
|
QString typFile(ProgramPaths::typFile());
|
|
if (QFileInfo::exists(typFile)) {
|
|
SubFile typ(&typFile);
|
|
_style = new Style(ratio, &typ);
|
|
} else
|
|
_style = new Style(ratio);
|
|
}
|
|
}
|
|
|
|
void MapData::clear()
|
|
{
|
|
TileTree::Iterator it;
|
|
for (_tileTree.GetFirst(it); !_tileTree.IsNull(it); _tileTree.GetNext(it))
|
|
_tileTree.GetAt(it)->clear();
|
|
|
|
delete _style;
|
|
_style = 0;
|
|
|
|
_polyCache.clear();
|
|
_pointCache.clear();
|
|
_demCache.clear();
|
|
}
|
|
|
|
void MapData::computeZooms()
|
|
{
|
|
TileTree::Iterator it;
|
|
QSet<Zoom> zooms;
|
|
|
|
for (_tileTree.GetFirst(it); !_tileTree.IsNull(it); _tileTree.GetNext(it)) {
|
|
const QVector<Zoom> &z = _tileTree.GetAt(it)->zooms();
|
|
for (int i = 0; i < z.size(); i++)
|
|
zooms.insert(z.at(i));
|
|
}
|
|
|
|
if (zooms.isEmpty())
|
|
return;
|
|
|
|
_zooms = zooms.values();
|
|
std::sort(_zooms.begin(), _zooms.end());
|
|
|
|
bool baseMap = false;
|
|
for (int i = 1; i < _zooms.size(); i++) {
|
|
if (_zooms.at(i).level() > _zooms.at(i-1).level()) {
|
|
baseMap = true;
|
|
break;
|
|
}
|
|
}
|
|
_zoomLevels = Range(baseMap ? _zooms.first().bits()
|
|
: qMax(0, _zooms.first().bits() - 2), 28);
|
|
}
|
|
|
|
const Zoom &MapData::zoom(int bits) const
|
|
{
|
|
int id = 0;
|
|
|
|
for (int i = 1; i < _zooms.size(); i++) {
|
|
if (_zooms.at(i).bits() > bits)
|
|
break;
|
|
id++;
|
|
}
|
|
|
|
return _zooms.at(id);
|
|
}
|