summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Angelelli <paolo.angelelli@qt.io>2017-08-03 11:47:29 +0200
committerPaolo Angelelli <paolo.angelelli@qt.io>2018-07-26 11:40:43 +0000
commite079d8d8d8cd4f9e4bd85abdf39804075e34517b (patch)
tree21a4f05d92dd63ca020a81c5459e4308965a4e7a
parentabcb5d1bccbc5913b7d994e0ad2685d484c35740 (diff)
downloadqtlocation-e079d8d8d8cd4f9e4bd85abdf39804075e34517b.tar.gz
Remove indexing of offline data from OSM plugin
With this patch, offline tiles will be looked up on the fly, thus removing the need to index the offline content at startup. Task-number: QTBUG-59665 Change-Id: I1db62c38363dafe82ee2f2ffc7f493ac5d958fc2 Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
-rw-r--r--src/plugins/geoservices/osm/qgeofiletilecacheosm.cpp137
-rw-r--r--src/plugins/geoservices/osm/qgeofiletilecacheosm.h9
2 files changed, 41 insertions, 105 deletions
diff --git a/src/plugins/geoservices/osm/qgeofiletilecacheosm.cpp b/src/plugins/geoservices/osm/qgeofiletilecacheosm.cpp
index a759edf4..d79702cf 100644
--- a/src/plugins/geoservices/osm/qgeofiletilecacheosm.cpp
+++ b/src/plugins/geoservices/osm/qgeofiletilecacheosm.cpp
@@ -49,14 +49,17 @@ QGeoFileTileCacheOsm::QGeoFileTileCacheOsm(const QVector<QGeoTileProviderOsm *>
const QString &offlineDirectory,
const QString &directory,
QObject *parent)
-: QGeoFileTileCache(directory, parent), m_offlineDirectory(offlineDirectory), m_providers(providers)
+: QGeoFileTileCache(directory, parent), m_offlineDirectory(offlineDirectory), m_offlineData(false), m_providers(providers)
{
m_highDpi.resize(providers.size());
+ if (!offlineDirectory.isEmpty()) {
+ m_offlineDirectory = QDir(offlineDirectory);
+ if (m_offlineDirectory.exists())
+ m_offlineData = true;
+ }
for (int i = 0; i < providers.size(); i++) {
providers[i]->setParent(this);
m_highDpi[i] = providers[i]->isHighDpi();
- m_mapIdFutures[providers[i]->mapType().mapId()].isFinished(); // To construct a default future for this mapId
- m_requestCancel[providers[i]->mapType().mapId()] = 0;
connect(providers[i], &QGeoTileProviderOsm::resolutionFinished, this, &QGeoFileTileCacheOsm::onProviderResolutionFinished);
connect(providers[i], &QGeoTileProviderOsm::resolutionError, this, &QGeoFileTileCacheOsm::onProviderResolutionFinished);
}
@@ -64,10 +67,6 @@ QGeoFileTileCacheOsm::QGeoFileTileCacheOsm(const QVector<QGeoTileProviderOsm *>
QGeoFileTileCacheOsm::~QGeoFileTileCacheOsm()
{
- for (const QGeoTileProviderOsm *p : m_providers) {
- m_requestCancel[p->mapType().mapId()] = 1;
- m_mapIdFutures[p->mapType().mapId()].waitForFinished();
- }
}
QSharedPointer<QGeoTileTexture> QGeoFileTileCacheOsm::get(const QGeoTileSpec &spec)
@@ -89,21 +88,10 @@ void QGeoFileTileCacheOsm::onProviderResolutionFinished(const QGeoTileProviderOs
int mapId = m_providers[i]->mapType().mapId();
m_highDpi[i] = m_providers[i]->isHighDpi();
- // Terminate initOfflineRegistry future for mapId.
- if (!m_offlineDirectory.isEmpty()) {
- m_requestCancel[mapId] = 1;
- m_mapIdFutures[mapId].waitForFinished();
- m_requestCancel[mapId] = 0;
- }
-
// reload cache for mapId i
dropTiles(mapId);
loadTiles(mapId);
- // reload offline registry for mapId i
- if (!m_offlineDirectory.isEmpty())
- m_mapIdFutures[mapId] = QtConcurrent::run(this, &QGeoFileTileCacheOsm::initOfflineRegistry, mapId);
-
// send signal to clear scene in all maps created through this provider that use the reloaded tiles
emit mapDataUpdated(mapId);
}
@@ -152,37 +140,38 @@ void QGeoFileTileCacheOsm::init()
// Base class ::init()
QGeoFileTileCache::init();
- for (QGeoTileProviderOsm * p: m_providers) {
+ for (QGeoTileProviderOsm * p: m_providers)
clearObsoleteTiles(p);
- if (!m_offlineDirectory.isEmpty())
- m_mapIdFutures[p->mapType().mapId()] = QtConcurrent::run(this, &QGeoFileTileCacheOsm::initOfflineRegistry, p->mapType().mapId());
- }
}
QSharedPointer<QGeoTileTexture> QGeoFileTileCacheOsm::getFromOfflineStorage(const QGeoTileSpec &spec)
{
- QMutexLocker locker(&storageLock);
- if (m_tilespecToOfflineFilepath.contains(spec)) {
- const QString fileName = m_tilespecToOfflineFilepath[spec];
- locker.unlock();
- QFile file(fileName);
- file.open(QIODevice::ReadOnly);
- QByteArray bytes = file.readAll();
- file.close();
-
- QImage image;
- if (!image.loadFromData(bytes)) {
- handleError(spec, QLatin1String("Problem with tile image"));
- return QSharedPointer<QGeoTileTexture>(0);
- }
+ if (!m_offlineData)
+ return QSharedPointer<QGeoTileTexture>();
- addToMemoryCache(spec, bytes, QString());
- QSharedPointer<QGeoTileTexture> tt = addToTextureCache(spec, image);
- if (tt)
- return tt;
+ int providerId = spec.mapId() - 1;
+ if (providerId < 0 || providerId >= m_providers.size())
+ return QSharedPointer<QGeoTileTexture>();
+
+ const QString fileName = tileSpecToFilename(spec, QStringLiteral("*"), providerId);
+ QStringList validTiles = m_offlineDirectory.entryList({fileName});
+ if (!validTiles.size())
+ return QSharedPointer<QGeoTileTexture>();
+
+ QFile file(m_offlineDirectory.absoluteFilePath(validTiles.first()));
+ if (!file.open(QIODevice::ReadOnly))
+ return QSharedPointer<QGeoTileTexture>();
+ QByteArray bytes = file.readAll();
+ file.close();
+
+ QImage image;
+ if (!image.loadFromData(bytes)) {
+ handleError(spec, QLatin1String("Problem with tile image"));
+ return QSharedPointer<QGeoTileTexture>(0);
}
- return QSharedPointer<QGeoTileTexture>();
+ addToMemoryCache(spec, bytes, QString());
+ return addToTextureCache(spec, image);
}
void QGeoFileTileCacheOsm::dropTiles(int mapId)
@@ -202,11 +191,6 @@ void QGeoFileTileCacheOsm::dropTiles(int mapId)
for (const QGeoTileSpec &k : keys)
if (k.mapId() == mapId)
diskCache_.remove(k);
-
- keys = m_tilespecToOfflineFilepath.keys();
- for (const QGeoTileSpec &k : keys)
- if (k.mapId() == mapId)
- m_tilespecToOfflineFilepath.remove(k);
}
void QGeoFileTileCacheOsm::loadTiles(int mapId)
@@ -226,60 +210,18 @@ void QGeoFileTileCacheOsm::loadTiles(int mapId)
}
}
-void QGeoFileTileCacheOsm::initOfflineRegistry(int mapId)
-{
- if (mapId < 1) // map ids in osm start from 1
- return;
-
- // Dealing with duplicates: picking the newest
- QMap<QString, QPair<QString, QDateTime> > fileDates; // key is filename, value is <filepath, lastmodified>
- QDirIterator it(m_offlineDirectory, QStringList() << "*.*", QDir::Files, QDirIterator::Subdirectories | QDirIterator::FollowSymlinks );
- while (it.hasNext()) {
- const QString &path = it.next();
- QFileInfo f(path);
- if (!fileDates.contains(f.fileName()) || fileDates[f.fileName()].second < f.lastModified())
- fileDates[f.fileName()] = QPair<QString, QDateTime>(f.filePath(), f.lastModified());
- if (m_requestCancel[mapId])
- return;
- }
-
- // Clear the content of the index. Entirely (at startup), or selectively (when a provider resolution changes the highDpi status).
- QList<QGeoTileSpec> toRemove;
- for (auto i = m_tilespecToOfflineFilepath.constBegin(); i != m_tilespecToOfflineFilepath.constEnd(); ++i) {
- if (i.key().mapId() == mapId)
- toRemove.append(i.key());
- }
- storageLock.lock();
- for (const auto &i : toRemove)
- m_tilespecToOfflineFilepath.remove(i);
- storageLock.unlock();
-
- if (m_requestCancel[mapId])
- return;
-
- // Fill the index by mapId
- int count = 0;
- for (auto i= fileDates.constBegin(); i != fileDates.constEnd(); ++i) {
- QGeoTileSpec spec = filenameToTileSpec(i.key());
- if (spec.zoom() == -1)
- continue;
- if (spec.mapId() != mapId)
- continue;
- count++;
- storageLock.lock();
- m_tilespecToOfflineFilepath[spec] = i.value().first;
- storageLock.unlock();
- if (m_requestCancel[mapId])
- return;
- }
- //qInfo() << "OSM plugin has found and is using "<< count <<" offline tiles";
-}
-
QString QGeoFileTileCacheOsm::tileSpecToFilename(const QGeoTileSpec &spec, const QString &format, const QString &directory) const
{
int providerId = spec.mapId() - 1;
if (providerId < 0 || providerId >= m_providers.size())
return QString();
+
+ QDir dir = QDir(directory);
+ return dir.filePath(tileSpecToFilename(spec, format, providerId));
+}
+
+QString QGeoFileTileCacheOsm::tileSpecToFilename(const QGeoTileSpec &spec, const QString &format, int providerId) const
+{
QString filename = spec.plugin();
filename += QLatin1String("-");
filename += (m_providers[providerId]->isHighDpi()) ? QLatin1Char('h') : QLatin1Char('l');
@@ -300,10 +242,7 @@ QString QGeoFileTileCacheOsm::tileSpecToFilename(const QGeoTileSpec &spec, const
filename += QLatin1String(".");
filename += format;
-
- QDir dir = QDir(directory);
-
- return dir.filePath(filename);
+ return filename;
}
QGeoTileSpec QGeoFileTileCacheOsm::filenameToTileSpec(const QString &filename) const
diff --git a/src/plugins/geoservices/osm/qgeofiletilecacheosm.h b/src/plugins/geoservices/osm/qgeofiletilecacheosm.h
index 5f11004c..da1fd0d3 100644
--- a/src/plugins/geoservices/osm/qgeofiletilecacheosm.h
+++ b/src/plugins/geoservices/osm/qgeofiletilecacheosm.h
@@ -66,20 +66,17 @@ protected Q_SLOTS:
protected:
void init() override;
+ inline QString tileSpecToFilename(const QGeoTileSpec &spec, const QString &format, int providerId) const;
QString tileSpecToFilename(const QGeoTileSpec &spec, const QString &format, const QString &directory) const override;
QGeoTileSpec filenameToTileSpec(const QString &filename) const override;
QSharedPointer<QGeoTileTexture> getFromOfflineStorage(const QGeoTileSpec &spec);
void dropTiles(int mapId);
void loadTiles(int mapId);
- void initOfflineRegistry(int mapId);
void clearObsoleteTiles(const QGeoTileProviderOsm *p);
- QString m_offlineDirectory;
- QHash<QGeoTileSpec, QString> m_tilespecToOfflineFilepath;
- QMap<int, QAtomicInt> m_requestCancel;
- QMap<int, QFuture<void>> m_mapIdFutures;
- QMutex storageLock;
+ QDir m_offlineDirectory;
+ bool m_offlineData;
QVector<QGeoTileProviderOsm *> m_providers;
QVector<bool> m_highDpi;
QVector<QDateTime> m_maxMapIdTimestamps;