summaryrefslogtreecommitdiff
path: root/src/plugins/geoservices/osm/qgeofiletilecacheosm.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/geoservices/osm/qgeofiletilecacheosm.cpp')
-rw-r--r--src/plugins/geoservices/osm/qgeofiletilecacheosm.cpp142
1 files changed, 139 insertions, 3 deletions
diff --git a/src/plugins/geoservices/osm/qgeofiletilecacheosm.cpp b/src/plugins/geoservices/osm/qgeofiletilecacheosm.cpp
index a780faa9..a8429f3d 100644
--- a/src/plugins/geoservices/osm/qgeofiletilecacheosm.cpp
+++ b/src/plugins/geoservices/osm/qgeofiletilecacheosm.cpp
@@ -45,10 +45,16 @@
QT_BEGIN_NAMESPACE
-QGeoFileTileCacheOsm::QGeoFileTileCacheOsm(const QString &offlineDirectory, const QString &directory, QObject *parent)
- :QGeoFileTileCache(directory, parent), m_offlineDirectory(offlineDirectory),
- m_requestCancel(0)
+QGeoFileTileCacheOsm::QGeoFileTileCacheOsm(const QVector<QGeoTileProviderOsm *> &providers, const QString &offlineDirectory, const QString &directory, QObject *parent)
+: QGeoFileTileCache(directory, parent), m_offlineDirectory(offlineDirectory),
+ m_requestCancel(0), m_providers(providers)
{
+ m_highDpi.resize(providers.size());
+ for (int i = 0; i < providers.size(); i++) {
+ m_highDpi[i] = providers[i]->isHighDpi();
+ connect(providers[i], &QGeoTileProviderOsm::resolutionFinished, this, &QGeoFileTileCacheOsm::onProviderResolutionFinished);
+ connect(providers[i], &QGeoTileProviderOsm::resolutionError, this, &QGeoFileTileCacheOsm::onProviderResolutionFinished);
+ }
}
QGeoFileTileCacheOsm::~QGeoFileTileCacheOsm()
@@ -67,6 +73,24 @@ QSharedPointer<QGeoTileTexture> QGeoFileTileCacheOsm::get(const QGeoTileSpec &sp
return getFromDisk(spec);
}
+void QGeoFileTileCacheOsm::onProviderResolutionFinished(const QGeoTileProviderOsm *provider)
+{
+ Q_UNUSED(provider)
+ for (int i = 0; i < m_providers.size(); i++) {
+ if (m_providers[i]->isHighDpi() != m_highDpi[i]) {
+ int mapId = m_providers[i]->mapType().mapId();
+ m_highDpi[i] = m_providers[i]->isHighDpi();
+
+ // reload cache for mapId i
+ dropTiles(mapId);
+ loadTiles(mapId);
+
+ // send signal to clear scene in all maps created through this provider that use the reloaded tiles
+ emit mapDataUpdated(mapId);
+ }
+ }
+}
+
void QGeoFileTileCacheOsm::init()
{
QGeoFileTileCache::init();
@@ -99,6 +123,42 @@ QSharedPointer<QGeoTileTexture> QGeoFileTileCacheOsm::getFromOfflineStorage(cons
return QSharedPointer<QGeoTileTexture>();
}
+void QGeoFileTileCacheOsm::dropTiles(int mapId)
+{
+ QList<QGeoTileSpec> keys;
+ keys = textureCache_.keys();
+ for (const QGeoTileSpec &k : keys)
+ if (k.mapId() == mapId)
+ textureCache_.remove(k);
+
+ keys = memoryCache_.keys();
+ for (const QGeoTileSpec &k : keys)
+ if (k.mapId() == mapId)
+ memoryCache_.remove(k);
+
+ keys = diskCache_.keys();
+ for (const QGeoTileSpec &k : keys)
+ if (k.mapId() == mapId)
+ diskCache_.remove(k);
+}
+
+void QGeoFileTileCacheOsm::loadTiles(int mapId)
+{
+ QStringList formats;
+ formats << QLatin1String("*.*");
+
+ QDir dir(directory_);
+ QStringList files = dir.entryList(formats, QDir::Files);
+
+ for (int i = 0; i < files.size(); ++i) {
+ QGeoTileSpec spec = filenameToTileSpec(files.at(i));
+ if (spec.zoom() == -1 || spec.mapId() != mapId)
+ continue;
+ QString filename = dir.filePath(files.at(i));
+ addToDiskCache(spec, filename);
+ }
+}
+
void QGeoFileTileCacheOsm::initOfflineRegistry()
{
// Dealing with duplicates: picking the newest
@@ -128,4 +188,80 @@ void QGeoFileTileCacheOsm::initOfflineRegistry()
qWarning() << "OSM Offline tiles: "<<count;
}
+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();
+ QString filename = spec.plugin();
+ filename += QLatin1String("-");
+ filename += (m_providers[providerId]->isHighDpi()) ? QLatin1Char('h') : QLatin1Char('l');
+ filename += QLatin1String("-");
+ filename += QString::number(spec.mapId());
+ filename += QLatin1String("-");
+ filename += QString::number(spec.zoom());
+ filename += QLatin1String("-");
+ filename += QString::number(spec.x());
+ filename += QLatin1String("-");
+ filename += QString::number(spec.y());
+
+ //Append version if real version number to ensure backwards compatibility and eviction of old tiles
+ if (spec.version() != -1) {
+ filename += QLatin1String("-");
+ filename += QString::number(spec.version());
+ }
+
+ filename += QLatin1String(".");
+ filename += format;
+
+ QDir dir = QDir(directory);
+
+ return dir.filePath(filename);
+}
+
+QGeoTileSpec QGeoFileTileCacheOsm::filenameToTileSpec(const QString &filename) const
+{
+ QGeoTileSpec emptySpec;
+
+ QStringList parts = filename.split('.');
+
+ if (parts.length() != 2)
+ return emptySpec;
+
+ QString name = parts.at(0);
+ QStringList fields = name.split('-');
+
+ int length = fields.length();
+ if (length != 6 && length != 7)
+ return emptySpec;
+
+ QList<int> numbers;
+
+ bool ok = false;
+ for (int i = 2; i < length; ++i) {
+ ok = false;
+ int value = fields.at(i).toInt(&ok);
+ if (!ok)
+ return emptySpec;
+ numbers.append(value);
+ }
+
+ bool highDpi = m_providers[numbers.at(0) - 1]->isHighDpi();
+ if (highDpi && fields.at(1) != QLatin1Char('h'))
+ return emptySpec;
+ else if (!highDpi && fields.at(1) != QLatin1Char('l'))
+ return emptySpec;
+
+ //File name without version, append default
+ if (numbers.length() < 5)
+ numbers.append(-1);
+
+ return QGeoTileSpec(fields.at(0),
+ numbers.at(0),
+ numbers.at(1),
+ numbers.at(2),
+ numbers.at(3),
+ numbers.at(4));
+}
+
QT_END_NAMESPACE