summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/location/maps/qgeotiledmap.cpp7
-rw-r--r--src/location/maps/qgeotiledmapscene.cpp42
-rw-r--r--src/location/maps/qgeotilerequestmanager.cpp25
-rw-r--r--src/location/maps/qgeotilerequestmanager_p.h2
4 files changed, 62 insertions, 14 deletions
diff --git a/src/location/maps/qgeotiledmap.cpp b/src/location/maps/qgeotiledmap.cpp
index 68f150db..450cdd44 100644
--- a/src/location/maps/qgeotiledmap.cpp
+++ b/src/location/maps/qgeotiledmap.cpp
@@ -320,12 +320,11 @@ void QGeoTiledMapPrivate::updateScene()
q->evaluateCopyrights(tiles);
// don't request tiles that are already built and textured
- QList<QSharedPointer<QGeoTileTexture> > cachedTiles =
+ QMap<QGeoTileSpec, QSharedPointer<QGeoTileTexture> > cachedTiles =
m_tileRequests->requestTiles(m_visibleTiles->createTiles() - m_mapScene->texturedTiles());
- foreach (const QSharedPointer<QGeoTileTexture> &tex, cachedTiles) {
- m_mapScene->addTile(tex->spec, tex);
- }
+ for (auto it = cachedTiles.cbegin(); it != cachedTiles.cend(); ++it)
+ m_mapScene->addTile(it.key(), it.value());
if (!cachedTiles.isEmpty())
emit q->sgNodeChanged();
diff --git a/src/location/maps/qgeotiledmapscene.cpp b/src/location/maps/qgeotiledmapscene.cpp
index d38eec39..977b4764 100644
--- a/src/location/maps/qgeotiledmapscene.cpp
+++ b/src/location/maps/qgeotiledmapscene.cpp
@@ -88,6 +88,7 @@ public:
double m_mapEdgeSize;
QHash<QGeoTileSpec, QSharedPointer<QGeoTileTexture> > m_textures;
+ QVector<QGeoTileSpec> m_updatedTextures;
// tilesToGrid transform
int m_minTileX; // the minimum tile index, i.e. 0 to sideLength which is 1<< zoomLevel
@@ -164,9 +165,9 @@ QSet<QGeoTileSpec> QGeoTiledMapScene::texturedTiles()
{
Q_D(QGeoTiledMapScene);
QSet<QGeoTileSpec> textured;
- foreach (const QGeoTileSpec &tile, d->m_textures.keys()) {
- textured += tile;
- }
+ for (auto it = d->m_textures.cbegin(); it != d->m_textures.cend(); ++it)
+ textured += it.value()->spec;
+
return textured;
}
@@ -227,7 +228,19 @@ bool QGeoTiledMapScenePrivate::buildGeometry(const QGeoTileSpec &spec, QSGImageN
imageNode->setRect(QRectF(QPointF(x1, y2), QPointF(x2, y1)));
imageNode->setTextureCoordinatesTransform(QSGImageNode::MirrorVertically);
- imageNode->setSourceRect(QRectF(QPointF(0,0), imageNode->texture()->textureSize()));
+
+ // Calculate the texture mapping, in case we are magnifying some lower ZL tile
+ const QGeoTileSpec textureSpec = m_textures.value(spec)->spec;
+ if (textureSpec.zoom() < spec.zoom()) {
+ // Currently only using lower ZL tiles for the overzoom.
+ const int tilesPerTexture = 1 << (spec.zoom() - textureSpec.zoom());
+ const int mappedSize = imageNode->texture()->textureSize().width() / tilesPerTexture;
+ const int x = (spec.x() % tilesPerTexture) * mappedSize;
+ const int y = (spec.y() % tilesPerTexture) * mappedSize;
+ imageNode->setSourceRect(QRectF(x, y, mappedSize, mappedSize));
+ } else {
+ imageNode->setSourceRect(QRectF(QPointF(0,0), imageNode->texture()->textureSize()));
+ }
return true;
}
@@ -237,6 +250,8 @@ void QGeoTiledMapScenePrivate::addTile(const QGeoTileSpec &spec, QSharedPointer<
if (!m_visibleTiles.contains(spec)) // Don't add the geometry if it isn't visible
return;
+ if (m_textures.contains(spec))
+ m_updatedTextures.append(spec);
m_textures.insert(spec, texture);
}
@@ -644,6 +659,25 @@ QSGNode *QGeoTiledMapScene::updateSceneGraph(QSGNode *oldNode, QQuickWindow *win
d->m_dropTextures = false;
}
+ // Evicting loZL tiles temporarily used in place of hiZL ones
+ if (d->m_updatedTextures.size()) {
+ const QVector<QGeoTileSpec> &toRemove = d->m_updatedTextures;
+ for (const QGeoTileSpec &s : toRemove) {
+ if (mapRoot->tiles->tiles.contains(s))
+ delete mapRoot->tiles->tiles.take(s);
+
+ if (mapRoot->wrapLeft->tiles.contains(s))
+ delete mapRoot->wrapLeft->tiles.take(s);
+
+ if (mapRoot->wrapRight->tiles.contains(s))
+ delete mapRoot->wrapRight->tiles.take(s);
+
+ if (mapRoot->textures.contains(s))
+ mapRoot->textures.take(s)->deleteLater();
+ }
+ d->m_updatedTextures.clear();
+ }
+
QSet<QGeoTileSpec> textures = QSet<QGeoTileSpec>::fromList(mapRoot->textures.keys());
QSet<QGeoTileSpec> toRemove = textures - d->m_visibleTiles;
QSet<QGeoTileSpec> toAdd = d->m_visibleTiles - textures;
diff --git a/src/location/maps/qgeotilerequestmanager.cpp b/src/location/maps/qgeotilerequestmanager.cpp
index 1409856a..7672a98f 100644
--- a/src/location/maps/qgeotilerequestmanager.cpp
+++ b/src/location/maps/qgeotilerequestmanager.cpp
@@ -53,7 +53,7 @@ public:
QGeoTiledMap *m_map;
QPointer<QGeoTiledMappingManagerEngine> m_engine;
- QList<QSharedPointer<QGeoTileTexture> > requestTiles(const QSet<QGeoTileSpec> &tiles);
+ QMap<QGeoTileSpec, QSharedPointer<QGeoTileTexture> > requestTiles(const QSet<QGeoTileSpec> &tiles);
void tileError(const QGeoTileSpec &tile, const QString &errorString);
QHash<QGeoTileSpec, int> m_retries;
@@ -74,7 +74,7 @@ QGeoTileRequestManager::~QGeoTileRequestManager()
}
-QList<QSharedPointer<QGeoTileTexture> > QGeoTileRequestManager::requestTiles(const QSet<QGeoTileSpec> &tiles)
+QMap<QGeoTileSpec, QSharedPointer<QGeoTileTexture> > QGeoTileRequestManager::requestTiles(const QSet<QGeoTileSpec> &tiles)
{
return d_ptr->requestTiles(tiles);
}
@@ -107,7 +107,7 @@ QGeoTileRequestManagerPrivate::~QGeoTileRequestManagerPrivate()
{
}
-QList<QSharedPointer<QGeoTileTexture> > QGeoTileRequestManagerPrivate::requestTiles(const QSet<QGeoTileSpec> &tiles)
+QMap<QGeoTileSpec, QSharedPointer<QGeoTileTexture> > QGeoTileRequestManagerPrivate::requestTiles(const QSet<QGeoTileSpec> &tiles)
{
QSet<QGeoTileSpec> cancelTiles = m_requested - tiles;
QSet<QGeoTileSpec> requestTiles = tiles - m_requested;
@@ -117,7 +117,7 @@ QList<QSharedPointer<QGeoTileTexture> > QGeoTileRequestManagerPrivate::requestTi
typedef QSet<QGeoTileSpec>::const_iterator iter;
- QList<QSharedPointer<QGeoTileTexture> > cachedTex;
+ QMap<QGeoTileSpec, QSharedPointer<QGeoTileTexture> > cachedTex;
// remove tiles in cache from request tiles
if (!m_engine.isNull()) {
@@ -127,8 +127,23 @@ QList<QSharedPointer<QGeoTileTexture> > QGeoTileRequestManagerPrivate::requestTi
QGeoTileSpec tile = *i;
QSharedPointer<QGeoTileTexture> tex = m_engine->getTileTexture(tile);
if (tex) {
- cachedTex << tex;
+ cachedTex.insert(tile, tex);
cached.insert(tile);
+ } else {
+ // Try to use textures from lower zoom levels, but still request the proper tile
+ QGeoTileSpec spec = tile;
+ const int endRange = qMax(0, tile.zoom() - 4); // Using up to 4 zoom levels up. 4 is arbitrary.
+ for (int z = tile.zoom() - 1; z >= endRange; z--) {
+ int denominator = 1 << (tile.zoom() - z);
+ spec.setZoom(z);
+ spec.setX(tile.x() / denominator);
+ spec.setY(tile.y() / denominator);
+ QSharedPointer<QGeoTileTexture> t = m_engine->getTileTexture(spec);
+ if (t) {
+ cachedTex.insert(tile, t);
+ break;
+ }
+ }
}
}
}
diff --git a/src/location/maps/qgeotilerequestmanager_p.h b/src/location/maps/qgeotilerequestmanager_p.h
index 66d2251e..f8ea4814 100644
--- a/src/location/maps/qgeotilerequestmanager_p.h
+++ b/src/location/maps/qgeotilerequestmanager_p.h
@@ -64,7 +64,7 @@ public:
explicit QGeoTileRequestManager(QGeoTiledMap *map, QGeoTiledMappingManagerEngine *engine);
~QGeoTileRequestManager();
- QList<QSharedPointer<QGeoTileTexture> > requestTiles(const QSet<QGeoTileSpec> &tiles);
+ QMap<QGeoTileSpec, QSharedPointer<QGeoTileTexture> > requestTiles(const QSet<QGeoTileSpec> &tiles);
void tileError(const QGeoTileSpec &tile, const QString &errorString);
void tileFetched(const QGeoTileSpec &spec);