summaryrefslogtreecommitdiff
path: root/src/plugins/geoservices/osm
diff options
context:
space:
mode:
authorPaolo Angelelli <paolo.angelelli@qt.io>2017-02-28 15:05:01 +0000
committerThe Qt Project <gerrit-noreply@qt-project.org>2017-02-28 15:46:39 +0000
commit3027558cf4094c7d290731c9d819201c6d570c13 (patch)
tree30e8ba6628cb7886f1dd6eef886196a64e07cbaa /src/plugins/geoservices/osm
parent65bd308685d6c863f4f684efa7a593d76cbdec3b (diff)
parent461da8f31a90b3ed5e98133850f0776c5e0c2a2d (diff)
downloadqtlocation-3027558cf4094c7d290731c9d819201c6d570c13.tar.gz
Merge "Merge remote-tracking branch 'gerrit/5.8' into 5.9" into refs/staging/5.9
Diffstat (limited to 'src/plugins/geoservices/osm')
-rw-r--r--src/plugins/geoservices/osm/qgeofiletilecacheosm.cpp77
-rw-r--r--src/plugins/geoservices/osm/qgeofiletilecacheosm.h5
-rw-r--r--src/plugins/geoservices/osm/qgeotileproviderosm.cpp2
3 files changed, 49 insertions, 35 deletions
diff --git a/src/plugins/geoservices/osm/qgeofiletilecacheosm.cpp b/src/plugins/geoservices/osm/qgeofiletilecacheosm.cpp
index a36f15b3..a759edf4 100644
--- a/src/plugins/geoservices/osm/qgeofiletilecacheosm.cpp
+++ b/src/plugins/geoservices/osm/qgeofiletilecacheosm.cpp
@@ -49,13 +49,14 @@ QGeoFileTileCacheOsm::QGeoFileTileCacheOsm(const QVector<QGeoTileProviderOsm *>
const QString &offlineDirectory,
const QString &directory,
QObject *parent)
-: QGeoFileTileCache(directory, parent), m_offlineDirectory(offlineDirectory), m_requestCancel(0), m_providers(providers)
+: QGeoFileTileCache(directory, parent), m_offlineDirectory(offlineDirectory), m_providers(providers)
{
m_highDpi.resize(providers.size());
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);
}
@@ -63,10 +64,10 @@ QGeoFileTileCacheOsm::QGeoFileTileCacheOsm(const QVector<QGeoTileProviderOsm *>
QGeoFileTileCacheOsm::~QGeoFileTileCacheOsm()
{
- m_requestCancel = 1;
- m_future.waitForFinished();
- for (const QGeoTileProviderOsm *p : m_providers)
+ 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)
@@ -88,12 +89,20 @@ 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
- m_mapIdFutures[mapId] = QtConcurrent::run(this, &QGeoFileTileCacheOsm::initOfflineRegistry, mapId);
+ 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);
@@ -101,7 +110,8 @@ void QGeoFileTileCacheOsm::onProviderResolutionFinished(const QGeoTileProviderOs
}
}
-// On resolution error the provider is removed ONLY if there is no enabled hardcoded fallback.
+// On resolution error the provider is removed.
+// This happens ONLY if there is no enabled hardcoded fallback for the mapId.
// Hardcoded fallbacks also have a timestamp, that can get updated with Qt releases.
void QGeoFileTileCacheOsm::onProviderResolutionError(const QGeoTileProviderOsm *provider, QNetworkReply::NetworkError error)
{
@@ -109,6 +119,7 @@ void QGeoFileTileCacheOsm::onProviderResolutionError(const QGeoTileProviderOsm *
clearObsoleteTiles(provider); // this still removes tiles who happen to be older than qgeotileproviderosm.cpp defaultTs
}
+// init() is always called before the provider resolution starts
void QGeoFileTileCacheOsm::init()
{
if (directory_.isEmpty())
@@ -141,22 +152,23 @@ 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_future = QtConcurrent::run(this, &QGeoFileTileCacheOsm::initOfflineRegistry, -1);
+ 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)) {
- QFile file(m_tilespecToOfflineFilepath[spec]);
+ const QString fileName = m_tilespecToOfflineFilepath[spec];
+ locker.unlock();
+ QFile file(fileName);
file.open(QIODevice::ReadOnly);
QByteArray bytes = file.readAll();
file.close();
- locker.unlock();
QImage image;
if (!image.loadFromData(bytes)) {
@@ -190,6 +202,11 @@ 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)
@@ -211,6 +228,9 @@ 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 );
@@ -219,42 +239,37 @@ void QGeoFileTileCacheOsm::initOfflineRegistry(int mapId)
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)
+ if (m_requestCancel[mapId])
return;
}
// Clear the content of the index. Entirely (at startup), or selectively (when a provider resolution changes the highDpi status).
- if (mapId < 0) {
- storageLock.lock();
- m_tilespecToOfflineFilepath.clear();
- storageLock.unlock();
- } else {
- 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();
+ QList<QGeoTileSpec> toRemove;
+ for (auto i = m_tilespecToOfflineFilepath.constBegin(); i != m_tilespecToOfflineFilepath.constEnd(); ++i) {
+ if (i.key().mapId() == mapId)
+ toRemove.append(i.key());
}
- if (m_requestCancel)
+ storageLock.lock();
+ for (const auto &i : toRemove)
+ m_tilespecToOfflineFilepath.remove(i);
+ storageLock.unlock();
+
+ if (m_requestCancel[mapId])
return;
- // Fill the index entirely or selectively
+ // 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 (mapId >= 0 && spec.mapId() != mapId) // if mapId != -1, pick up only those files with that mapId.
+ if (spec.mapId() != mapId)
continue;
count++;
storageLock.lock();
m_tilespecToOfflineFilepath[spec] = i.value().first;
storageLock.unlock();
- if (m_requestCancel)
+ if (m_requestCancel[mapId])
return;
}
//qInfo() << "OSM plugin has found and is using "<< count <<" offline tiles";
diff --git a/src/plugins/geoservices/osm/qgeofiletilecacheosm.h b/src/plugins/geoservices/osm/qgeofiletilecacheosm.h
index d26cad4a..f26e7f10 100644
--- a/src/plugins/geoservices/osm/qgeofiletilecacheosm.h
+++ b/src/plugins/geoservices/osm/qgeofiletilecacheosm.h
@@ -72,13 +72,12 @@ protected:
void dropTiles(int mapId);
void loadTiles(int mapId);
- void initOfflineRegistry(int mapId = -1);
+ void initOfflineRegistry(int mapId);
void clearObsoleteTiles(const QGeoTileProviderOsm *p);
QString m_offlineDirectory;
QHash<QGeoTileSpec, QString> m_tilespecToOfflineFilepath;
- QAtomicInt m_requestCancel;
- QFuture<void> m_future;
+ QMap<int, QAtomicInt> m_requestCancel;
QMap<int, QFuture<void>> m_mapIdFutures;
QMutex storageLock;
QVector<QGeoTileProviderOsm *> m_providers;
diff --git a/src/plugins/geoservices/osm/qgeotileproviderosm.cpp b/src/plugins/geoservices/osm/qgeotileproviderosm.cpp
index 1b48401c..ad8edfd5 100644
--- a/src/plugins/geoservices/osm/qgeotileproviderosm.cpp
+++ b/src/plugins/geoservices/osm/qgeotileproviderosm.cpp
@@ -191,7 +191,7 @@ void QGeoTileProviderOsm::onResolutionError(TileProvider *provider)
{
Q_UNUSED(provider)
// provider and m_provider are the same at this point. m_status is Resolving.
- if (m_provider->isInvalid()) {
+ if (!m_provider || m_provider->isInvalid()) {
m_provider = nullptr;
m_status = Resolved;
if (m_providerId >= m_providerList.size() -1) { // no hope left