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:
parent
d0dc3661e4
commit
fd65882907
@ -344,4 +344,6 @@ void RasterTile::render()
|
||||
//painter.drawRect(QRect(_rect.topLeft(), _pixmap.size()));
|
||||
|
||||
qDeleteAll(textItems);
|
||||
|
||||
_valid = true;
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user