C
Qt Quick Ultralite map example
// Copyright (C) 2025 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
#include "offlinetilefetcher.h"
#include <qul/private/qulrcc_lookup.h>
OfflineTileFetcher::OfflineTileFetcher(bool useFileCache)
: m_fileCache(useFileCache ? Qul::Private::FileCache::instance() : nullptr)
, maxCacheSize(MAX_CACHE_SIZE)
{}
Qul::SharedImage OfflineTileFetcher::findImage(const char *url)
{
if (m_fileCache)
return m_fileCache->get(url);
return Qul::Private::findImageForString(url);
}
bool OfflineTileFetcher::getTileImage(const Qul::Private::TileSpec &spec, Qul::Private::TileImage &tileImage)
{
// user has to configure url to point to tiles images root dir.
QulString url = generateTileUrl(TILES_BASE_DIR, spec);
if (url.empty()) {
url = PLACEHOLDER_TILE;
Qul::PlatformInterface::log("warning: tile url is empty. using placeholder tile at '%s'.\n", PLACEHOLDER_TILE);
}
const TileCacheMap::iterator it = tileCache.find(url);
if (it != tileCache.end()) {
tileImage.texture = it->second.texture();
return true;
}
if (tileCache.size() >= maxCacheSize)
removeOldestImage();
Qul::SharedImage newTileImage = findImage(url.c_str());
if (!newTileImage && url != PLACEHOLDER_TILE) {
#ifndef NDEBUG
Qul::PlatformInterface::log("warning: could not fetch a tile with url '%s'. using placeholder tile.\n",
url.c_str());
#endif
newTileImage = findImage(PLACEHOLDER_TILE);
if (!newTileImage) {
Qul::PlatformInterface::log("error: could not fetch a placeholder tile from '%s'.\n", PLACEHOLDER_TILE);
return false;
}
} else if (!newTileImage) {
Qul::PlatformInterface::log("error: could not fetch a placeholder tile from '%s'.\n", PLACEHOLDER_TILE);
return false;
}
tileImage.texture = newTileImage.texture();
tileCache[url] = newTileImage;
cacheOrder.push_back(url);
return true;
}
void OfflineTileFetcher::removeOldestImage()
{
for (int i = 0; i < MAX_CACHE_SIZE / 5 && !cacheOrder.empty(); ++i) {
const QulString oldestUrl = cacheOrder.front();
cacheOrder.pop_front();
tileCache.erase(oldestUrl);
}
}
OfflineTileFetcher::QulString OfflineTileFetcher::generateTileUrl(const char *baseDir,
const Qul::Private::TileSpec &spec) const
{
const int size = std::snprintf(nullptr, 0, "%s%d/%d/%d.jpeg", baseDir, spec.zoom, spec.x, spec.y) + 1;
if (size <= 0) {
Qul::PlatformInterface::log("error: failed to calculate the required buffer size for the tile url.");
return QulString();
}
char *buffer = static_cast<char *>(Qul::Platform::qul_malloc(sizeof(char) * size));
if (!buffer) {
Qul::PlatformInterface::log("error: failed to allocate memory for the tile url.");
return QulString();
}
std::snprintf(buffer, size, "%s%d/%d/%d.jpeg", baseDir, spec.zoom, spec.x, spec.y);
QulString url(buffer);
Qul::Platform::qul_free(buffer);
return url;
}