62void QGeoFileTileCache::init()
64 const QString basePath = baseCacheDirectory() + QLatin1String(
"QtLocation/");
69 QDir baseDir(basePath);
70 if (baseDir.exists()) {
71 const QStringList oldCacheFiles = baseDir.entryList(QDir::Files);
72 for (
const QString& file : oldCacheFiles)
74 const QStringList oldCacheDirs = { QStringLiteral(
"osm"), QStringLiteral(
"mapbox"), QStringLiteral(
"here") };
75 for (
const QString& d : oldCacheDirs) {
76 QDir oldCacheDir(basePath + QLatin1Char(
'/') + d);
77 if (oldCacheDir.exists())
78 oldCacheDir.removeRecursively();
82 if (directory_.isEmpty()) {
83 directory_ = baseLocationCacheDirectory();
84 qWarning() <<
"Plugin uses uninitialized QGeoFileTileCache directory which was deleted during startup";
87 const bool directoryCreated = QDir::root().mkpath(directory_);
88 if (!directoryCreated)
89 qWarning() <<
"Failed to create cache directory " << directory_;
92 if (!isDiskCostSet_) {
93 if (costStrategyDisk_ == ByteSize)
94 setMaxDiskUsage(50 * 1024 * 1024);
96 setMaxDiskUsage(1000);
99 if (!isMemoryCostSet_) {
100 if (costStrategyMemory_ == ByteSize)
101 setMaxMemoryUsage(3 * 1024 * 1024);
103 setMaxMemoryUsage(100);
106 if (!isTextureCostSet_) {
107 if (costStrategyTexture_ == ByteSize)
108 setExtraTextureUsage(6 * 1024 * 1024);
110 setExtraTextureUsage(30);
116void QGeoFileTileCache::loadTiles()
119 formats << QLatin1String(
"*.*");
121 QDir dir(directory_);
122 const QStringList files = dir.entryList(formats, QDir::Files);
127 for (
int i = 1; i<=4; i++) {
128 QString filename = dir.filePath(QString::fromLatin1(
"queue") + QString::number(i));
129 QFile file(filename);
130 if (!file.open(QIODevice::ReadOnly))
132 QList<QSharedPointer<QGeoCachedTileDisk> > queue;
133 QList<QGeoTileSpec> specs;
135 while (!file.atEnd()) {
136 QByteArray line = file.readLine().trimmed();
137 QString filename = QString::fromLatin1(line.constData(), line.length());
138 if (dir.exists(filename)){
139 files.removeOne(filename);
140 QGeoTileSpec spec = filenameToTileSpec(filename);
141 if (spec.zoom() == -1)
143 QSharedPointer<QGeoCachedTileDisk> tileDisk(
new QGeoCachedTileDisk);
144 tileDisk->filename = dir.filePath(filename);
145 tileDisk->cache =
this;
146 tileDisk->spec = spec;
147 QFileInfo fi(tileDisk->filename);
149 queue.append(tileDisk);
150 if (costStrategyDisk_ == ByteSize)
151 costs.append(fi.size());
158 diskCache_.deserializeQueue(i, specs, queue, costs);
165 for (
const auto &file : files) {
166 QGeoTileSpec spec = filenameToTileSpec(file);
167 if (spec.zoom() == -1)
169 QString filename = dir.filePath(file);
170 addToDiskCache(spec, filename);
174QGeoFileTileCache::~QGeoFileTileCache()
178 QDir dir(directory_);
179 for (
int i = 1; i<=4; i++) {
180 QString filename = dir.filePath(QString::fromLatin1(
"queue") + QString::number(i));
181 QFile file(filename);
182 if (!file.open(QIODevice::WriteOnly)){
183 qWarning() <<
"Unable to write tile cache file " << filename;
186 QList<QSharedPointer<QGeoCachedTileDisk> > queue;
187 diskCache_.serializeQueue(i, queue);
188 for (
const QSharedPointer<QGeoCachedTileDisk> &tile : queue) {
193 int index = tile->filename.lastIndexOf(QLatin1Char(
'/'));
194 QByteArray filename = tile->filename.mid(index + 1).toLatin1() +
'\n';
195 file.write(filename);
270void QGeoFileTileCache::clearAll()
272 textureCache_.clear();
273 memoryCache_.clear();
275 QDir dir(directory_);
276 dir.setNameFilters(QStringList() << QLatin1String(
"*-*-*-*.*"));
277 dir.setFilter(QDir::Files);
278 const auto entries = dir.entryList();
279 for (
const QString &dirFile : entries) {
284void QGeoFileTileCache::clearMapId(
const int mapId)
287 const auto keys = diskCache_.keys();
288 for (
const QGeoTileSpec &k : keys)
289 if (k.mapId() == mapId)
290 diskCache_.remove(k,
true);
293 const auto keys = memoryCache_.keys();
294 for (
const QGeoTileSpec &k : keys)
295 if (k.mapId() == mapId)
296 memoryCache_.remove(k);
299 const auto keys = textureCache_.keys();
300 for (
const QGeoTileSpec &k : keys)
301 if (k.mapId() == mapId)
302 textureCache_.remove(k);
308 QDir dir(directory_);
310 formats << QLatin1String(
"*.*");
311 const QStringList files = dir.entryList(formats, QDir::Files);
312 qWarning() <<
"Old tile data detected. Cache eviction left out "<< files.size() <<
"tiles";
313 for (
const QString &tileFileName : files) {
314 QGeoTileSpec spec = filenameToTileSpec(tileFileName);
315 if (spec.mapId() != mapId)
317 QFile::remove(dir.filePath(tileFileName));
359void QGeoFileTileCache::insert(
const QGeoTileSpec &spec,
360 const QByteArray &bytes,
361 const QString &format,
362 QAbstractGeoTileCache::CacheAreas areas)
367 if (areas & QAbstractGeoTileCache::DiskCache) {
368 QString filename = tileSpecToFilename(spec, format, directory_);
369 addToDiskCache(spec, filename, bytes);
372 if (areas & QAbstractGeoTileCache::MemoryCache) {
373 addToMemoryCache(spec, bytes, format);
377
378
381QString QGeoFileTileCache::tileSpecToFilenameDefault(
const QGeoTileSpec &spec,
const QString &format,
const QString &directory)
383 QString filename = spec.plugin();
384 filename += QLatin1String(
"-");
385 filename += QString::number(spec.mapId());
386 filename += QLatin1String(
"-");
387 filename += QString::number(spec.zoom());
388 filename += QLatin1String(
"-");
389 filename += QString::number(spec.x());
390 filename += QLatin1String(
"-");
391 filename += QString::number(spec.y());
394 if (spec.version() != -1) {
395 filename += QLatin1String(
"-");
396 filename += QString::number(spec.version());
399 filename += QLatin1String(
".");
402 QDir dir = QDir(directory);
404 return dir.filePath(filename);
407QGeoTileSpec QGeoFileTileCache::filenameToTileSpecDefault(
const QString &filename)
409 QGeoTileSpec emptySpec;
411 const QStringList parts = filename.split(QLatin1Char(
'.'));
413 if (parts.length() != 2)
416 const QString name = parts.at(0);
417 const QStringList fields = name.split(QLatin1Char(
'-'));
419 qsizetype length = fields.length();
420 if (length != 5 && length != 6)
426 for (qsizetype i = 1; i < length; ++i) {
428 int value = fields.at(i).toInt(&ok);
431 numbers.append(value);
435 if (numbers.length() < 5)
438 return QGeoTileSpec(fields.at(0),
455QSharedPointer<QGeoCachedTileDisk> QGeoFileTileCache::addToDiskCache(
const QGeoTileSpec &spec,
const QString &filename)
457 QSharedPointer<QGeoCachedTileDisk> td(
new QGeoCachedTileDisk);
459 td->filename = filename;
463 if (costStrategyDisk_ == ByteSize) {
464 QFileInfo fi(filename);
467 diskCache_.insert(spec, td, cost);
471bool QGeoFileTileCache::addToDiskCache(
const QGeoTileSpec &spec,
const QString &filename,
const QByteArray &bytes)
474 if (costStrategyDisk_ == ByteSize)
477 if (cost > diskCache_.maxCost())
480 QSaveFile file(filename);
481 if (!file.open(QIODevice::WriteOnly))
487 QSharedPointer<QGeoCachedTileDisk> td(
new QGeoCachedTileDisk);
489 td->filename = filename;
492 [[maybe_unused]]
const bool inserted = diskCache_.insert(spec, td, cost);
498void QGeoFileTileCache::addToMemoryCache(
const QGeoTileSpec &spec,
const QByteArray &bytes,
const QString &format)
500 if (isTileBogus(bytes))
503 QSharedPointer<QGeoCachedTileMemory> tm(
new QGeoCachedTileMemory);
510 if (costStrategyMemory_ == ByteSize)
512 memoryCache_.insert(spec, tm, cost);
515QSharedPointer<QGeoTileTexture> QGeoFileTileCache::addToTextureCache(
const QGeoTileSpec &spec,
const QImage &image)
517 QSharedPointer<QGeoTileTexture> tt(
new QGeoTileTexture);
522 if (costStrategyTexture_ == ByteSize)
523 cost = image.width() * image.height() * image.depth() / 8;
524 textureCache_.insert(spec, tt, cost);
529QSharedPointer<QGeoTileTexture> QGeoFileTileCache::getFromMemory(
const QGeoTileSpec &spec)
531 QSharedPointer<QGeoTileTexture> tt = textureCache_.object(spec);
535 QSharedPointer<QGeoCachedTileMemory> tm = memoryCache_.object(spec);
538 if (!image.loadFromData(tm->bytes)) {
539 handleError(spec, QLatin1String(
"Problem with tile image"));
540 return QSharedPointer<QGeoTileTexture>();
542 QSharedPointer<QGeoTileTexture> tt = addToTextureCache(spec, image);
546 return QSharedPointer<QGeoTileTexture>();
549QSharedPointer<QGeoTileTexture> QGeoFileTileCache::getFromDisk(
const QGeoTileSpec &spec)
551 QSharedPointer<QGeoCachedTileDisk> td = diskCache_.object(spec);
553 const QString format = QFileInfo(td->filename).suffix();
554 QFile file(td->filename);
555 if (!file.open(QIODevice::ReadOnly)) {
556 handleError(spec,
"Cannot open file %1: %2"_L1.arg(file.fileName(), file.errorString()));
559 QByteArray bytes = file.readAll();
566 if (isTileBogus(bytes)) {
567 QSharedPointer<QGeoTileTexture> tt(
new QGeoTileTexture);
574 if (!image.loadFromData(bytes)) {
575 handleError(spec, QLatin1String(
"Problem with tile image"));
576 return QSharedPointer<QGeoTileTexture>();
580 if (image.format() != QImage::Format_RGB32 && image.format() != QImage::Format_ARGB32_Premultiplied)
581 image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
583 addToMemoryCache(spec, bytes, format);
584 QSharedPointer<QGeoTileTexture> tt = addToTextureCache(td->spec, image);
589 return QSharedPointer<QGeoTileTexture>();