14QGeoFileTileCacheOsm::QGeoFileTileCacheOsm(
const QList<QGeoTileProviderOsm *> &providers,
15 const QString &offlineDirectory,
16 const QString &directory, QObject *parent)
17 : QGeoFileTileCache(directory, parent),
18 m_offlineDirectory(offlineDirectory),
20 m_providers(providers)
22 m_highDpi.resize(providers.size());
23 if (!offlineDirectory.isEmpty()) {
24 m_offlineDirectory = QDir(offlineDirectory);
25 if (m_offlineDirectory.exists())
28 for (
int i = 0; i < providers.size(); i++) {
29 providers[i]->setParent(
this);
30 m_highDpi[i] = providers[i]->isHighDpi();
31 connect(providers[i], &QGeoTileProviderOsm::resolutionFinished,
this, &QGeoFileTileCacheOsm::onProviderResolutionFinished);
32 connect(providers[i], &QGeoTileProviderOsm::resolutionError,
this, &QGeoFileTileCacheOsm::onProviderResolutionFinished);
81 if (directory_.isEmpty())
82 directory_ = baseLocationCacheDirectory();
83 QDir::root().mkpath(directory_);
87 for (
auto p: std::as_const(m_providers))
88 if (p->mapType().mapId() > max)
89 max = p->mapType().mapId();
91 m_maxMapIdTimestamps.resize(max+1);
96 formats << QLatin1String(
"*.*");
97 const QStringList files = dir.entryList(formats, QDir::Files);
99 for (
const QString &tileFileName : files) {
100 QGeoTileSpec spec = filenameToTileSpec(tileFileName);
101 if (spec.zoom() == -1)
103 QFileInfo fi(dir.filePath(tileFileName));
104 if (fi.lastModified() > m_maxMapIdTimestamps[spec.mapId()])
105 m_maxMapIdTimestamps[spec.mapId()] = fi.lastModified();
109 QGeoFileTileCache::init();
111 for (QGeoTileProviderOsm * p: std::as_const(m_providers))
112 clearObsoleteTiles(p);
118 return QSharedPointer<QGeoTileTexture>();
120 int providerId = spec.mapId() - 1;
121 if (providerId < 0 || providerId >= m_providers.size())
122 return QSharedPointer<QGeoTileTexture>();
124 const QString fileName = tileSpecToFilename(spec, QStringLiteral(
"*"), providerId);
125 QStringList validTiles = m_offlineDirectory.entryList({fileName});
126 if (!validTiles.size())
127 return QSharedPointer<QGeoTileTexture>();
129 QFile file(m_offlineDirectory.absoluteFilePath(validTiles.first()));
130 if (!file.open(QIODevice::ReadOnly))
131 return QSharedPointer<QGeoTileTexture>();
132 QByteArray bytes = file.readAll();
136 if (!image.loadFromData(bytes)) {
137 handleError(spec, QLatin1String(
"Problem with tile image"));
138 return QSharedPointer<QGeoTileTexture>();
141 addToMemoryCache(spec, bytes, QString());
142 return addToTextureCache(spec, image);
172 formats << QLatin1String(
"*.*");
174 QDir dir(directory_);
175 QStringList files = dir.entryList(formats, QDir::Files);
177 for (
int i = 0; i < files.size(); ++i) {
178 QGeoTileSpec spec = filenameToTileSpec(files.at(i));
179 if (spec.zoom() == -1 || spec.mapId() != mapId)
181 QString filename = dir.filePath(files.at(i));
182 addToDiskCache(spec, filename);
198 QString filename = spec.plugin();
199 filename += QLatin1String(
"-");
200 filename += (m_providers[providerId]->isHighDpi()) ? QLatin1Char(
'h') : QLatin1Char(
'l');
201 filename += QLatin1String(
"-");
202 filename += QString::number(spec.mapId());
203 filename += QLatin1String(
"-");
204 filename += QString::number(spec.zoom());
205 filename += QLatin1String(
"-");
206 filename += QString::number(spec.x());
207 filename += QLatin1String(
"-");
208 filename += QString::number(spec.y());
211 if (spec.version() != -1) {
212 filename += QLatin1String(
"-");
213 filename += QString::number(spec.version());
216 filename += QLatin1String(
".");
223 QGeoTileSpec emptySpec;
225 QStringList parts = filename.split(
'.');
227 if (parts.length() != 2)
230 QString name = parts.at(0);
231 QStringList fields = name.split(
'-');
233 int length = fields.length();
234 if (length != 6 && length != 7)
240 for (
int i = 2; i < length; ++i) {
242 int value = fields.at(i).toInt(&ok);
245 numbers.append(value);
248 if (numbers.at(0) > m_providers.size())
251 bool highDpi = m_providers[numbers.at(0) - 1]->isHighDpi();
252 if (highDpi && fields.at(1) != QLatin1Char(
'h'))
254 else if (!highDpi && fields.at(1) != QLatin1Char(
'l'))
258 if (numbers.length() < 5)
261 return QGeoTileSpec(fields.at(0),
274 if (m_maxMapIdTimestamps[p->mapType().mapId()].isValid() &&
275 p->timestamp() > m_maxMapIdTimestamps[p->mapType().mapId()]) {
276 qInfo() <<
"provider for " << p->mapType().name() <<
" timestamp: " << p->timestamp()
277 <<
" -- data last modified: " << m_maxMapIdTimestamps[p->mapType().mapId()] <<
". Clearing.";
278 clearMapId(p->mapType().mapId());
279 m_maxMapIdTimestamps[p->mapType().mapId()] = p->timestamp();
282 connect(p, &QGeoTileProviderOsm::resolutionFinished,
283 this, &QGeoFileTileCacheOsm::onProviderResolutionFinished);
285 connect(p, &QGeoTileProviderOsm::resolutionError,
286 this, &QGeoFileTileCacheOsm::onProviderResolutionError);