13QGeoFileTileCacheOsm::QGeoFileTileCacheOsm(
const QList<QGeoTileProviderOsm *> &providers,
14 const QString &offlineDirectory,
15 const QString &directory, QObject *parent)
16 : QGeoFileTileCache(directory, parent),
17 m_offlineDirectory(offlineDirectory),
19 m_providers(providers)
21 m_highDpi.resize(providers.size());
22 if (!offlineDirectory.isEmpty()) {
23 m_offlineDirectory = QDir(offlineDirectory);
24 if (m_offlineDirectory.exists())
27 for (
int i = 0; i < providers.size(); i++) {
28 providers[i]->setParent(
this);
29 m_highDpi[i] = providers[i]->isHighDpi();
30 connect(providers[i], &QGeoTileProviderOsm::resolutionFinished,
this, &QGeoFileTileCacheOsm::onProviderResolutionFinished);
31 connect(providers[i], &QGeoTileProviderOsm::resolutionError,
this, &QGeoFileTileCacheOsm::onProviderResolutionFinished);
80 if (directory_.isEmpty())
81 directory_ = baseLocationCacheDirectory();
82 QDir::root().mkpath(directory_);
86 for (
auto p: m_providers)
87 if (p->mapType().mapId() > max)
88 max = p->mapType().mapId();
90 m_maxMapIdTimestamps.resize(max+1);
95 formats << QLatin1String(
"*.*");
96 QStringList files = dir.entryList(formats, QDir::Files);
98 for (
const QString &tileFileName : files) {
99 QGeoTileSpec spec = filenameToTileSpec(tileFileName);
100 if (spec.zoom() == -1)
102 QFileInfo fi(dir.filePath(tileFileName));
103 if (fi.lastModified() > m_maxMapIdTimestamps[spec.mapId()])
104 m_maxMapIdTimestamps[spec.mapId()] = fi.lastModified();
108 QGeoFileTileCache::init();
110 for (QGeoTileProviderOsm * p: m_providers)
111 clearObsoleteTiles(p);
117 return QSharedPointer<QGeoTileTexture>();
119 int providerId = spec.mapId() - 1;
120 if (providerId < 0 || providerId >= m_providers.size())
121 return QSharedPointer<QGeoTileTexture>();
123 const QString fileName = tileSpecToFilename(spec, QStringLiteral(
"*"), providerId);
124 QStringList validTiles = m_offlineDirectory.entryList({fileName});
125 if (!validTiles.size())
126 return QSharedPointer<QGeoTileTexture>();
128 QFile file(m_offlineDirectory.absoluteFilePath(validTiles.first()));
129 if (!file.open(QIODevice::ReadOnly))
130 return QSharedPointer<QGeoTileTexture>();
131 QByteArray bytes = file.readAll();
135 if (!image.loadFromData(bytes)) {
136 handleError(spec, QLatin1String(
"Problem with tile image"));
137 return QSharedPointer<QGeoTileTexture>();
140 addToMemoryCache(spec, bytes, QString());
141 return addToTextureCache(spec, image);
166 formats << QLatin1String(
"*.*");
168 QDir dir(directory_);
169 QStringList files = dir.entryList(formats, QDir::Files);
171 for (
int i = 0; i < files.size(); ++i) {
172 QGeoTileSpec spec = filenameToTileSpec(files.at(i));
173 if (spec.zoom() == -1 || spec.mapId() != mapId)
175 QString filename = dir.filePath(files.at(i));
176 addToDiskCache(spec, filename);
192 QString filename = spec.plugin();
193 filename += QLatin1String(
"-");
194 filename += (m_providers[providerId]->isHighDpi()) ? QLatin1Char(
'h') : QLatin1Char(
'l');
195 filename += QLatin1String(
"-");
196 filename += QString::number(spec.mapId());
197 filename += QLatin1String(
"-");
198 filename += QString::number(spec.zoom());
199 filename += QLatin1String(
"-");
200 filename += QString::number(spec.x());
201 filename += QLatin1String(
"-");
202 filename += QString::number(spec.y());
205 if (spec.version() != -1) {
206 filename += QLatin1String(
"-");
207 filename += QString::number(spec.version());
210 filename += QLatin1String(
".");
217 QGeoTileSpec emptySpec;
219 QStringList parts = filename.split(
'.');
221 if (parts.length() != 2)
224 QString name = parts.at(0);
225 QStringList fields = name.split(
'-');
227 int length = fields.length();
228 if (length != 6 && length != 7)
234 for (
int i = 2; i < length; ++i) {
236 int value = fields.at(i).toInt(&ok);
239 numbers.append(value);
242 if (numbers.at(0) > m_providers.size())
245 bool highDpi = m_providers[numbers.at(0) - 1]->isHighDpi();
246 if (highDpi && fields.at(1) != QLatin1Char(
'h'))
248 else if (!highDpi && fields.at(1) != QLatin1Char(
'l'))
252 if (numbers.length() < 5)
255 return QGeoTileSpec(fields.at(0),
268 if (m_maxMapIdTimestamps[p->mapType().mapId()].isValid() &&
269 p->timestamp() > m_maxMapIdTimestamps[p->mapType().mapId()]) {
270 qInfo() <<
"provider for " << p->mapType().name() <<
" timestamp: " << p->timestamp()
271 <<
" -- data last modified: " << m_maxMapIdTimestamps[p->mapType().mapId()] <<
". Clearing.";
272 clearMapId(p->mapType().mapId());
273 m_maxMapIdTimestamps[p->mapType().mapId()] = p->timestamp();
276 connect(p, &QGeoTileProviderOsm::resolutionFinished,
277 this, &QGeoFileTileCacheOsm::onProviderResolutionFinished);
279 connect(p, &QGeoTileProviderOsm::resolutionError,
280 this, &QGeoFileTileCacheOsm::onProviderResolutionError);