summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Angelelli <paolo.angelelli@qt.io>2017-05-04 20:46:53 +0200
committerJani Heikkinen <jani.heikkinen@qt.io>2017-05-08 08:58:04 +0000
commitd9a476f99216425ef3b76dfa054a9aab918b31be (patch)
treee3ac3d5e4104293c9111c798f6e9b0117be75c62
parent6e276607e507f36bd94c33652071cf0413c6ba3a (diff)
downloadqtlocation-d9a476f99216425ef3b76dfa054a9aab918b31be.tar.gz
Add a way to skip showing tiles
In certain cases servers provide tiles that can be fully transparent, provide no content or are bogus. Tile fetchers can be smart and detect some of these cases. This patch offers an extensible way to allow them to communicate (via a null QImage) tiles that should not be rendered, in addition to an extensible mechanism to identify such tiles on disk. The default way is by assuming that, once such tiles have been detected, the tile fetcher would simply write a file with "NoRetry" as content. Change-Id: I404bb4dcc38fdd33c412f7407601b47947e4ce8d Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
-rw-r--r--src/location/maps/qgeofiletilecache.cpp25
-rw-r--r--src/location/maps/qgeofiletilecache_p.h3
-rw-r--r--src/location/maps/qgeotiledmap.cpp2
-rw-r--r--src/location/maps/qgeotilerequestmanager.cpp5
4 files changed, 28 insertions, 7 deletions
diff --git a/src/location/maps/qgeofiletilecache.cpp b/src/location/maps/qgeofiletilecache.cpp
index d2d0070b..ede900bd 100644
--- a/src/location/maps/qgeofiletilecache.cpp
+++ b/src/location/maps/qgeofiletilecache.cpp
@@ -426,8 +426,11 @@ QSharedPointer<QGeoCachedTileDisk> QGeoFileTileCache::addToDiskCache(const QGeoT
return td;
}
-QSharedPointer<QGeoCachedTileMemory> QGeoFileTileCache::addToMemoryCache(const QGeoTileSpec &spec, const QByteArray &bytes, const QString &format)
+void QGeoFileTileCache::addToMemoryCache(const QGeoTileSpec &spec, const QByteArray &bytes, const QString &format)
{
+ if (isTileBogus(bytes))
+ return;
+
QSharedPointer<QGeoCachedTileMemory> tm(new QGeoCachedTileMemory);
tm->spec = spec;
tm->cache = this;
@@ -438,8 +441,6 @@ QSharedPointer<QGeoCachedTileMemory> QGeoFileTileCache::addToMemoryCache(const Q
if (costStrategyMemory_ == ByteSize)
cost = bytes.size();
memoryCache_.insert(spec, tm, cost);
-
- return tm;
}
QSharedPointer<QGeoTileTexture> QGeoFileTileCache::addToTextureCache(const QGeoTileSpec &spec, const QImage &image)
@@ -487,6 +488,17 @@ QSharedPointer<QGeoTileTexture> QGeoFileTileCache::getFromDisk(const QGeoTileSpe
file.close();
QImage image;
+ // Some tiles from the servers could be valid images but the tile fetcher
+ // might be able to recognize them as tiles that should not be shown.
+ // If that's the case, the tile fetcher should write "NoRetry" inside the file.
+ if (isTileBogus(bytes)) {
+ QSharedPointer<QGeoTileTexture> tt(new QGeoTileTexture);
+ tt->spec = spec;
+ tt->image = image;
+ return tt;
+ }
+
+ // This is a truly invalid image. The fetcher should try again.
if (!image.loadFromData(bytes)) {
handleError(spec, QLatin1String("Problem with tile image"));
return QSharedPointer<QGeoTileTexture>(0);
@@ -505,6 +517,13 @@ QSharedPointer<QGeoTileTexture> QGeoFileTileCache::getFromDisk(const QGeoTileSpe
return QSharedPointer<QGeoTileTexture>();
}
+bool QGeoFileTileCache::isTileBogus(const QByteArray &bytes) const
+{
+ if (bytes.size() == 7 && bytes == QByteArrayLiteral("NoRetry"))
+ return true;
+ return false;
+}
+
QString QGeoFileTileCache::tileSpecToFilename(const QGeoTileSpec &spec, const QString &format, const QString &directory) const
{
QString filename = spec.plugin();
diff --git a/src/location/maps/qgeofiletilecache_p.h b/src/location/maps/qgeofiletilecache_p.h
index 2da7c95f..2ae40d36 100644
--- a/src/location/maps/qgeofiletilecache_p.h
+++ b/src/location/maps/qgeofiletilecache_p.h
@@ -144,11 +144,12 @@ protected:
QString directory() const;
QSharedPointer<QGeoCachedTileDisk> addToDiskCache(const QGeoTileSpec &spec, const QString &filename);
- QSharedPointer<QGeoCachedTileMemory> addToMemoryCache(const QGeoTileSpec &spec, const QByteArray &bytes, const QString &format);
+ void addToMemoryCache(const QGeoTileSpec &spec, const QByteArray &bytes, const QString &format);
QSharedPointer<QGeoTileTexture> addToTextureCache(const QGeoTileSpec &spec, const QImage &image);
QSharedPointer<QGeoTileTexture> getFromMemory(const QGeoTileSpec &spec);
QSharedPointer<QGeoTileTexture> getFromDisk(const QGeoTileSpec &spec);
+ virtual bool isTileBogus(const QByteArray &bytes) const;
virtual QString tileSpecToFilename(const QGeoTileSpec &spec, const QString &format, const QString &directory) const;
virtual QGeoTileSpec filenameToTileSpec(const QString &filename) const;
diff --git a/src/location/maps/qgeotiledmap.cpp b/src/location/maps/qgeotiledmap.cpp
index dbfe45ea..0eeb189d 100644
--- a/src/location/maps/qgeotiledmap.cpp
+++ b/src/location/maps/qgeotiledmap.cpp
@@ -391,7 +391,7 @@ void QGeoTiledMapPrivate::updateTile(const QGeoTileSpec &spec)
// Only promote the texture up to GPU if it is visible
if (m_visibleTiles->createTiles().contains(spec)){
QSharedPointer<QGeoTileTexture> tex = m_tileRequests->tileTexture(spec);
- if (!tex.isNull()) {
+ if (!tex.isNull() && !tex->image.isNull()) {
m_mapScene->addTile(spec, tex);
emit q->sgNodeChanged();
}
diff --git a/src/location/maps/qgeotilerequestmanager.cpp b/src/location/maps/qgeotilerequestmanager.cpp
index 7672a98f..d4d94ad0 100644
--- a/src/location/maps/qgeotilerequestmanager.cpp
+++ b/src/location/maps/qgeotilerequestmanager.cpp
@@ -127,7 +127,8 @@ QMap<QGeoTileSpec, QSharedPointer<QGeoTileTexture> > QGeoTileRequestManagerPriva
QGeoTileSpec tile = *i;
QSharedPointer<QGeoTileTexture> tex = m_engine->getTileTexture(tile);
if (tex) {
- cachedTex.insert(tile, tex);
+ if (!tex->image.isNull())
+ cachedTex.insert(tile, tex);
cached.insert(tile);
} else {
// Try to use textures from lower zoom levels, but still request the proper tile
@@ -139,7 +140,7 @@ QMap<QGeoTileSpec, QSharedPointer<QGeoTileTexture> > QGeoTileRequestManagerPriva
spec.setX(tile.x() / denominator);
spec.setY(tile.y() / denominator);
QSharedPointer<QGeoTileTexture> t = m_engine->getTileTexture(spec);
- if (t) {
+ if (t && !t->image.isNull()) {
cachedTex.insert(tile, t);
break;
}