1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-11-28 05:34:47 +01:00

Do not render tiles that will not be shown due to zoom in/out

This commit is contained in:
Martin Tůma 2021-09-16 22:52:46 +02:00
parent d0dc3661e4
commit fd65882907
4 changed files with 71 additions and 50 deletions

View File

@ -344,4 +344,6 @@ void RasterTile::render()
//painter.drawRect(QRect(_rect.topLeft(), _pixmap.size()));
qDeleteAll(textItems);
_valid = true;
}

View File

@ -16,15 +16,16 @@ class RasterTile
{
public:
RasterTile(const Projection &proj, const Transform &transform, int zoom,
const QRect &rect, qreal ratio, const QString &key,
const QList<MapData::Path> &paths, const QList<MapData::Point> &points)
: _proj(proj), _transform(transform), _zoom(zoom), _rect(rect),
_ratio(ratio), _key(key), _pixmap(rect.width() * ratio,
rect.height() * ratio), _paths(paths), _points(points) {}
const QRect &rect, qreal ratio, const QList<MapData::Path> &paths,
const QList<MapData::Point> &points) : _proj(proj), _transform(transform),
_zoom(zoom), _rect(rect), _ratio(ratio),
_pixmap(rect.width() * ratio, rect.height() * ratio), _paths(paths),
_points(points), _valid(false) {}
const QString &key() const {return _key;}
int zoom() const {return _zoom;}
QPoint xy() const {return _rect.topLeft();}
const QPixmap &pixmap() const {return _pixmap;}
bool isValid() const {return _valid;}
void render();
@ -84,10 +85,10 @@ private:
int _zoom;
QRect _rect;
qreal _ratio;
QString _key;
QPixmap _pixmap;
QList<MapData::Path> _paths;
QList<MapData::Point> _points;
bool _valid;
};
inline HASH_T qHash(const RasterTile::Key &key)

View File

@ -60,6 +60,8 @@ int MapsforgeMap::zoomFit(const QSize &size, const RectC &rect)
int MapsforgeMap::zoomIn()
{
cancelJobs();
_zoom = qMin(_zoom + 1, _data.zooms().max());
updateTransform();
return _zoom;
@ -67,6 +69,8 @@ int MapsforgeMap::zoomIn()
int MapsforgeMap::zoomOut()
{
cancelJobs();
_zoom = qMax(_zoom - 1, _data.zooms().min());
updateTransform();
return _zoom;
@ -101,29 +105,59 @@ void MapsforgeMap::updateTransform()
_bounds.adjust(0.5, 0, -0.5, 0);
}
bool MapsforgeMap::isRunning(const QString &key) const
bool MapsforgeMap::isRunning(int zoom, const QPoint &xy) const
{
return _running.contains(key);
for (int i = 0; i < _jobs.size(); i++) {
const QList<Mapsforge::RasterTile> &tiles = _jobs.at(i)->tiles();
for (int j = 0; j < tiles.size(); j++) {
const Mapsforge::RasterTile &mt = tiles.at(j);
if (mt.zoom() == zoom && mt.xy() == xy)
return true;
}
}
return false;
}
void MapsforgeMap::addRunning(const QList<RasterTile> &tiles)
void MapsforgeMap::runJob(MapsforgeMapJob *job)
{
for (int i = 0; i < tiles.size(); i++)
_running.insert(tiles.at(i).key());
_jobs.append(job);
connect(job, &MapsforgeMapJob::finished, this, &MapsforgeMap::jobFinished);
job->run();
}
void MapsforgeMap::removeRunning(const QList<RasterTile> &tiles)
void MapsforgeMap::removeJob(MapsforgeMapJob *job)
{
for (int i = 0; i < tiles.size(); i++)
_running.remove(tiles.at(i).key());
_jobs.removeOne(job);
job->deleteLater();
}
void MapsforgeMap::jobFinished(const QList<RasterTile> &tiles)
void MapsforgeMap::jobFinished(MapsforgeMapJob *job)
{
removeRunning(tiles);
const QList<Mapsforge::RasterTile> &tiles = job->tiles();
for (int i = 0; i < tiles.size(); i++) {
const Mapsforge::RasterTile &mt = tiles.at(i);
if (!mt.isValid())
continue;
QString key = path() + "-" + QString::number(mt.zoom()) + "_"
+ QString::number(mt.xy().x()) + "_" + QString::number(mt.xy().y());
QPixmapCache::insert(key, mt.pixmap());
}
removeJob(job);
emit tilesLoaded();
}
void MapsforgeMap::cancelJobs()
{
for (int i = 0; i < _jobs.size(); i++)
_jobs.at(i)->cancel();
}
void MapsforgeMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
{
Q_UNUSED(flags);
@ -138,15 +172,15 @@ void MapsforgeMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
QPixmap pm;
QPoint ttl(tl.x() + i * _data.tileSize(), tl.y() + j
* _data.tileSize());
if (isRunning(_zoom, ttl))
continue;
QPixmap pm;
QString key = path() + "-" + QString::number(_zoom) + "_"
+ QString::number(ttl.x()) + "_" + QString::number(ttl.y());
if (isRunning(key))
continue;
if (QPixmapCache::find(key, &pm))
painter->drawPixmap(ttl, pm);
else {
@ -175,18 +209,13 @@ void MapsforgeMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
tiles.append(RasterTile(_projection, _transform, _zoom,
QRect(ttl, QSize(_data.tileSize(), _data.tileSize())),
_tileRatio, key, paths, points));
_tileRatio, paths, points));
}
}
}
if (!tiles.isEmpty()) {
MapsforgeMapJob *job = new MapsforgeMapJob(tiles);
connect(job, &MapsforgeMapJob::finished, this,
&MapsforgeMap::jobFinished);
addRunning(tiles);
job->run();
}
if (!tiles.isEmpty())
runJob(new MapsforgeMapJob(tiles));
}
void MapsforgeMap::setDevicePixelRatio(qreal deviceRatio, qreal mapRatio)

View File

@ -26,26 +26,14 @@ public:
_future = QtConcurrent::map(_tiles, &Mapsforge::RasterTile::render);
_watcher.setFuture(_future);
}
void cancel() {_future.cancel();}
const QList<Mapsforge::RasterTile> &tiles() const {return _tiles;}
signals:
void finished(const QList<Mapsforge::RasterTile> &);
void finished(MapsforgeMapJob *job);
private slots:
void handleFinished()
{
for (int i = 0; i < _tiles.size(); i++) {
Mapsforge::RasterTile &mt = _tiles[i];
const QPixmap &pm = mt.pixmap();
if (pm.isNull())
continue;
QPixmapCache::insert(mt.key(), pm);
}
emit finished(_tiles);
deleteLater();
}
void handleFinished() {emit finished(this);}
private:
QFutureWatcher<void> _watcher;
@ -85,14 +73,15 @@ public:
QString errorString() const {return _data.errorString();}
private slots:
void jobFinished(const QList<Mapsforge::RasterTile> &tiles);
void jobFinished(MapsforgeMapJob *job);
private:
Transform transform(int zoom) const;
void updateTransform();
bool isRunning(const QString &key) const;
void addRunning(const QList<Mapsforge::RasterTile> &tiles);
void removeRunning(const QList<Mapsforge::RasterTile> &tiles);
bool isRunning(int zoom, const QPoint &xy) const;
void runJob(MapsforgeMapJob *job);
void removeJob(MapsforgeMapJob *job);
void cancelJobs();
Mapsforge::MapData _data;
int _zoom;
@ -102,7 +91,7 @@ private:
QRectF _bounds;
qreal _tileRatio;
QSet<QString> _running;
QList<MapsforgeMapJob*> _jobs;
};
#endif // MAPSFORGEMAP_H