mirror of
https://github.com/tumic0/GPXSee.git
synced 2024-11-30 22:51:16 +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()));
|
//painter.drawRect(QRect(_rect.topLeft(), _pixmap.size()));
|
||||||
|
|
||||||
qDeleteAll(textItems);
|
qDeleteAll(textItems);
|
||||||
|
|
||||||
|
_valid = true;
|
||||||
}
|
}
|
||||||
|
@ -16,15 +16,16 @@ class RasterTile
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RasterTile(const Projection &proj, const Transform &transform, int zoom,
|
RasterTile(const Projection &proj, const Transform &transform, int zoom,
|
||||||
const QRect &rect, qreal ratio, const QString &key,
|
const QRect &rect, qreal ratio, const QList<MapData::Path> &paths,
|
||||||
const QList<MapData::Path> &paths, const QList<MapData::Point> &points)
|
const QList<MapData::Point> &points) : _proj(proj), _transform(transform),
|
||||||
: _proj(proj), _transform(transform), _zoom(zoom), _rect(rect),
|
_zoom(zoom), _rect(rect), _ratio(ratio),
|
||||||
_ratio(ratio), _key(key), _pixmap(rect.width() * ratio,
|
_pixmap(rect.width() * ratio, rect.height() * ratio), _paths(paths),
|
||||||
rect.height() * ratio), _paths(paths), _points(points) {}
|
_points(points), _valid(false) {}
|
||||||
|
|
||||||
const QString &key() const {return _key;}
|
int zoom() const {return _zoom;}
|
||||||
QPoint xy() const {return _rect.topLeft();}
|
QPoint xy() const {return _rect.topLeft();}
|
||||||
const QPixmap &pixmap() const {return _pixmap;}
|
const QPixmap &pixmap() const {return _pixmap;}
|
||||||
|
bool isValid() const {return _valid;}
|
||||||
|
|
||||||
void render();
|
void render();
|
||||||
|
|
||||||
@ -84,10 +85,10 @@ private:
|
|||||||
int _zoom;
|
int _zoom;
|
||||||
QRect _rect;
|
QRect _rect;
|
||||||
qreal _ratio;
|
qreal _ratio;
|
||||||
QString _key;
|
|
||||||
QPixmap _pixmap;
|
QPixmap _pixmap;
|
||||||
QList<MapData::Path> _paths;
|
QList<MapData::Path> _paths;
|
||||||
QList<MapData::Point> _points;
|
QList<MapData::Point> _points;
|
||||||
|
bool _valid;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline HASH_T qHash(const RasterTile::Key &key)
|
inline HASH_T qHash(const RasterTile::Key &key)
|
||||||
|
@ -60,6 +60,8 @@ int MapsforgeMap::zoomFit(const QSize &size, const RectC &rect)
|
|||||||
|
|
||||||
int MapsforgeMap::zoomIn()
|
int MapsforgeMap::zoomIn()
|
||||||
{
|
{
|
||||||
|
cancelJobs();
|
||||||
|
|
||||||
_zoom = qMin(_zoom + 1, _data.zooms().max());
|
_zoom = qMin(_zoom + 1, _data.zooms().max());
|
||||||
updateTransform();
|
updateTransform();
|
||||||
return _zoom;
|
return _zoom;
|
||||||
@ -67,6 +69,8 @@ int MapsforgeMap::zoomIn()
|
|||||||
|
|
||||||
int MapsforgeMap::zoomOut()
|
int MapsforgeMap::zoomOut()
|
||||||
{
|
{
|
||||||
|
cancelJobs();
|
||||||
|
|
||||||
_zoom = qMax(_zoom - 1, _data.zooms().min());
|
_zoom = qMax(_zoom - 1, _data.zooms().min());
|
||||||
updateTransform();
|
updateTransform();
|
||||||
return _zoom;
|
return _zoom;
|
||||||
@ -101,29 +105,59 @@ void MapsforgeMap::updateTransform()
|
|||||||
_bounds.adjust(0.5, 0, -0.5, 0);
|
_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++)
|
_jobs.append(job);
|
||||||
_running.insert(tiles.at(i).key());
|
|
||||||
|
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++)
|
_jobs.removeOne(job);
|
||||||
_running.remove(tiles.at(i).key());
|
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();
|
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)
|
void MapsforgeMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
|
||||||
{
|
{
|
||||||
Q_UNUSED(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 i = 0; i < width; i++) {
|
||||||
for (int j = 0; j < height; j++) {
|
for (int j = 0; j < height; j++) {
|
||||||
QPixmap pm;
|
|
||||||
QPoint ttl(tl.x() + i * _data.tileSize(), tl.y() + j
|
QPoint ttl(tl.x() + i * _data.tileSize(), tl.y() + j
|
||||||
* _data.tileSize());
|
* _data.tileSize());
|
||||||
|
if (isRunning(_zoom, ttl))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
QPixmap pm;
|
||||||
QString key = path() + "-" + QString::number(_zoom) + "_"
|
QString key = path() + "-" + QString::number(_zoom) + "_"
|
||||||
+ QString::number(ttl.x()) + "_" + QString::number(ttl.y());
|
+ QString::number(ttl.x()) + "_" + QString::number(ttl.y());
|
||||||
|
|
||||||
if (isRunning(key))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (QPixmapCache::find(key, &pm))
|
if (QPixmapCache::find(key, &pm))
|
||||||
painter->drawPixmap(ttl, pm);
|
painter->drawPixmap(ttl, pm);
|
||||||
else {
|
else {
|
||||||
@ -175,18 +209,13 @@ void MapsforgeMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
|
|||||||
|
|
||||||
tiles.append(RasterTile(_projection, _transform, _zoom,
|
tiles.append(RasterTile(_projection, _transform, _zoom,
|
||||||
QRect(ttl, QSize(_data.tileSize(), _data.tileSize())),
|
QRect(ttl, QSize(_data.tileSize(), _data.tileSize())),
|
||||||
_tileRatio, key, paths, points));
|
_tileRatio, paths, points));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tiles.isEmpty()) {
|
if (!tiles.isEmpty())
|
||||||
MapsforgeMapJob *job = new MapsforgeMapJob(tiles);
|
runJob(new MapsforgeMapJob(tiles));
|
||||||
connect(job, &MapsforgeMapJob::finished, this,
|
|
||||||
&MapsforgeMap::jobFinished);
|
|
||||||
addRunning(tiles);
|
|
||||||
job->run();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapsforgeMap::setDevicePixelRatio(qreal deviceRatio, qreal mapRatio)
|
void MapsforgeMap::setDevicePixelRatio(qreal deviceRatio, qreal mapRatio)
|
||||||
|
@ -26,26 +26,14 @@ public:
|
|||||||
_future = QtConcurrent::map(_tiles, &Mapsforge::RasterTile::render);
|
_future = QtConcurrent::map(_tiles, &Mapsforge::RasterTile::render);
|
||||||
_watcher.setFuture(_future);
|
_watcher.setFuture(_future);
|
||||||
}
|
}
|
||||||
|
void cancel() {_future.cancel();}
|
||||||
|
const QList<Mapsforge::RasterTile> &tiles() const {return _tiles;}
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void finished(const QList<Mapsforge::RasterTile> &);
|
void finished(MapsforgeMapJob *job);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void handleFinished()
|
void handleFinished() {emit finished(this);}
|
||||||
{
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QFutureWatcher<void> _watcher;
|
QFutureWatcher<void> _watcher;
|
||||||
@ -85,14 +73,15 @@ public:
|
|||||||
QString errorString() const {return _data.errorString();}
|
QString errorString() const {return _data.errorString();}
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void jobFinished(const QList<Mapsforge::RasterTile> &tiles);
|
void jobFinished(MapsforgeMapJob *job);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Transform transform(int zoom) const;
|
Transform transform(int zoom) const;
|
||||||
void updateTransform();
|
void updateTransform();
|
||||||
bool isRunning(const QString &key) const;
|
bool isRunning(int zoom, const QPoint &xy) const;
|
||||||
void addRunning(const QList<Mapsforge::RasterTile> &tiles);
|
void runJob(MapsforgeMapJob *job);
|
||||||
void removeRunning(const QList<Mapsforge::RasterTile> &tiles);
|
void removeJob(MapsforgeMapJob *job);
|
||||||
|
void cancelJobs();
|
||||||
|
|
||||||
Mapsforge::MapData _data;
|
Mapsforge::MapData _data;
|
||||||
int _zoom;
|
int _zoom;
|
||||||
@ -102,7 +91,7 @@ private:
|
|||||||
QRectF _bounds;
|
QRectF _bounds;
|
||||||
qreal _tileRatio;
|
qreal _tileRatio;
|
||||||
|
|
||||||
QSet<QString> _running;
|
QList<MapsforgeMapJob*> _jobs;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MAPSFORGEMAP_H
|
#endif // MAPSFORGEMAP_H
|
||||||
|
Loading…
Reference in New Issue
Block a user