Skip to content

TileCache

class nmeasim::app::map::TileCache · Applications

Serves map tiles from memory, then from a directory on disk, and finally by downloading them from a tile server.

Inherits QObject

Declared in src/app/map/tile_cache.hpp (line 54)

Up to 512 decoded tiles stay in memory, the least recently used leaving first. On disk the cache is a tree of PNG files, <directory>/<zoom>/<x>/<y>.png, which is unbounded and emptied only by clear. Downloads go through a QNetworkAccessManager owned by the cache: at most four run at a time and the rest wait in a first-in, first-out queue. Each request carries the User-Agent set with set_user_agent, follows only redirects that are no less safe (HTTPS stays HTTPS) and is aborted after 15 seconds without data. A tile is never requested twice at once. A downloaded tile is written to disk before tile_ready is emitted. Offline, no download is queued or running and tile reports tiles that are neither in memory nor on disk as missing.

A failed download is remembered, so that repainting the map does not request the tile again and again. A tile the server answered with HTTP 404 (Not Found) or 410 (Gone) is not requested again for the lifetime of the cache, unless the tile server changes. After any other failure (no network, a timeout, another HTTP error, a reply that is not an image) the tile is not requested again before a delay has passed: 30 seconds after the first failure, doubled after each further failure up to 10 minutes. Switching downloads back on forgets these delays, so that the tiles are tried again at once.

See also

  • MapWidget, which asks for the tiles covering its view on every paint.

Nested types

Type Description
TileCache::Failure A tile that failed to download.

Summary

Public member functions

Name Description
TileCache() Creates the cache on a directory, creating the directory if it does not exist.
url_template() Returns the tile server URL template.
set_url_template() Sets the tile server URL template used by later downloads.
online() Returns whether missing tiles are downloaded.
set_online() Switches downloading on or off.
set_user_agent() Sets the User-Agent header sent with every later tile request.
directory() Returns the root directory of the on-disk cache, as given to the constructor.
tile() Returns a tile from memory or disk, or queues its download.
is_cached() Returns whether a tile can be served without a download.
pending_downloads() Returns the number of downloads queued or running.
disk_size() Returns the space the tiles on disk take up.
clear() Removes every tile from memory and disk, empties the download queue and aborts the downloads already running.
set_retry_delay() Sets the delay before a tile that failed to download is requested again.

Signals

Name Description
tile_ready() Emitted when a downloaded tile has been decoded and cached.
tile_failed() Emitted when a download fails: a network or HTTP error, a timeout, or a reply that is not an image.

Private member functions

Name Description
path_of() Returns the file a tile is stored in on disk.
enqueue() Queues the download of a tile unless it is already queued or running, then starts downloads while fewer than four are running.
start_next() Starts queued downloads, oldest first, until four are running or the queue is empty.
finish() Handles a finished download: caches the tile on disk and in memory, emits tile_ready, or records the failure and emits tile_failed, and starts the next queued download.
record_failure() Remembers that a tile failed to download and when it may be requested again.
may_request() Returns whether a tile may be queued for download now.
abort_running() Aborts every running download without emitting a signal; the queued downloads stay.

Private static member functions

Name Description
memory_key() Returns the name of a tile in the memory cache and the download bookkeeping.

Private data members

Name Description
directory_ Root directory of the on-disk cache.
url_template_ Tile server URL with {z}, {x} and {y} placeholders; never empty.
user_agent_ Value of the User-Agent header sent with every request.
online_ Whether missing tiles are downloaded; false serves the disk cache only.
memory_ Decoded tiles by memory_key, at most 512, evicting the least recently used.
network_ Network access for the downloads, owned by the cache.
queued_ memory_key of every tile queued or running, so that a tile is requested only once at a time.
queue_ Tiles waiting for a download slot, oldest first.
running_ Running downloads by memory_key, at most four; the replies are owned by network_.
failures_ Failed downloads by memory_key, kept for the lifetime of the cache or until the tile server changes.
retry_delay_ Delay before a tile is requested again after its first failure.

Public member functions

TileCache()

explicit TileCache(QString directory, QObject* parent = nullptr)

Creates the cache on a directory, creating the directory if it does not exist.

The cache starts online, with the OpenStreetMap standard tile server https://tile.openstreetmap.org/{z}/{x}/{y}.png as URL template and the User-Agent NMEASimulatorX/<version> (+https://github.com/Dimitrios-Kafetzis/NMEA_Simulator_X), which names the application, its version and its project page, as the tile usage policy asks.

Parameters

Name Type Description
directory QString Root of the on-disk cache, which holds the tiles as <zoom>/<x>/<y>.png.
parent QObject* Qt parent that owns the cache; null leaves ownership with the caller.

Declared in src/app/map/tile_cache.hpp:69 · defined in src/app/map/tile_cache.cpp:59

url_template()

QString url_template() const noexcept

Returns the tile server URL template.

Returns QString: A URL whose {z}, {x} and {y} placeholders are replaced by the zoom level, the column and the row of a tile.

Declared in src/app/map/tile_cache.hpp:75

set_url_template()

void set_url_template(const QString& url_template)

Sets the tile server URL template used by later downloads.

Tiles already cached, in memory or on disk, stay and are served as before, even when they came from another server. When the template changes, the downloads running from the previous server are aborted without a signal, and the failures remembered for it are forgotten, HTTP 404 included.

Parameters

Name Type Description
url_template const QString& URL with {z}, {x} and {y} placeholders; surrounding white space is removed. An empty or blank template is ignored and the current one kept, so an unset preference keeps the OpenStreetMap default.

Declared in src/app/map/tile_cache.hpp:86 · defined in src/app/map/tile_cache.cpp:69

online()

bool online() const noexcept

Returns whether missing tiles are downloaded.

Returns bool: true when missing tiles are downloaded, false when the disk cache is the only source.

Declared in src/app/map/tile_cache.hpp:92

set_online()

void set_online(bool online)

Switches downloading on or off.

Switching off empties the download queue and aborts the downloads already running, which then cache nothing and emit no signal. Switching back on forgets the retry delays of tiles that failed, so that they are requested again at the next tile call; tiles the server reported as not found stay excluded.

Parameters

Name Type Description
online bool true to download missing tiles, false to serve the disk cache only.

Declared in src/app/map/tile_cache.hpp:101 · defined in src/app/map/tile_cache.cpp:82

set_user_agent()

void set_user_agent(const QString& user_agent)

Sets the User-Agent header sent with every later tile request.

Parameters

Name Type Description
user_agent const QString& Header value. The tile usage policy asks for one that identifies the application and a way to contact its authors.

Declared in src/app/map/tile_cache.hpp:107

directory()

QString directory() const noexcept

Returns the root directory of the on-disk cache, as given to the constructor.

Returns QString: The directory path.

Declared in src/app/map/tile_cache.hpp:111

tile()

std::optional<QPixmap> tile(const TileKey& key)

Returns a tile from memory or disk, or queues its download.

A tile read from disk is kept in memory for the next call. When the tile is in neither and the cache is online, its download is queued (once, however often it is asked for) and tile_ready or tile_failed is emitted once the reply finishes. No download is queued for a tile whose earlier download failed while its retry delay runs, nor ever again for a tile the server reported as not found.

Parameters

Name Type Description
key const TileKey& Tile to return.

Returns std::optional<QPixmap>: The tile image, or std::nullopt when it is neither in memory nor on disk.

Declared in src/app/map/tile_cache.hpp:123 · defined in src/app/map/tile_cache.cpp:116

is_cached()

bool is_cached(const TileKey& key) const

Returns whether a tile can be served without a download.

Unlike tile, this decodes nothing and never queues a download.

Parameters

Name Type Description
key const TileKey& Tile to look up.

Returns bool: true when the tile is in memory or its file exists on disk.

Declared in src/app/map/tile_cache.hpp:130 · defined in src/app/map/tile_cache.cpp:132

pending_downloads()

int pending_downloads() const

Returns the number of downloads queued or running.

Returns int: Queued plus running downloads; 0 when nothing is in flight.

Declared in src/app/map/tile_cache.hpp:135 · defined in src/app/map/tile_cache.cpp:136

disk_size()

qint64 disk_size() const

Returns the space the tiles on disk take up.

Walks the whole directory tree, so its cost grows with the number of cached tiles.

Returns qint64: Total size in bytes of the PNG files under directory().

Declared in src/app/map/tile_cache.hpp:141 · defined in src/app/map/tile_cache.cpp:140

clear()

void clear()

Removes every tile from memory and disk, empties the download queue and aborts the downloads already running.

The directory itself is recreated empty. An aborted download caches nothing and emits no signal. The remembered failures are kept.

Declared in src/app/map/tile_cache.hpp:147 · defined in src/app/map/tile_cache.cpp:150

set_retry_delay()

void set_retry_delay(std::chrono::milliseconds first_delay) noexcept

Sets the delay before a tile that failed to download is requested again.

The delay applies to the first failure of a tile; each further failure of the same tile doubles it, up to 10 minutes or first_delay, whichever is longer. Tiles the server reported as not found are never retried, whatever the delay. Delays already running are not changed.

Parameters

Name Type Description
first_delay std::chrono::milliseconds Delay after the first failure; 30 seconds by default. Zero or negative retries at the next tile call.

Declared in src/app/map/tile_cache.hpp:158

Signals

tile_ready()

void tile_ready(const nmeasim::app::map::TileKey& key)

Emitted when a downloaded tile has been decoded and cached.

Emitted when the network reply finishes, after the tile has been written to disk and put in memory. The next tile call for key returns the image.

Parameters

Name Type Description
key const nmeasim::app::map::TileKey& Tile that became available.

Declared in src/app/map/tile_cache.hpp:169

tile_failed()

void tile_failed(const nmeasim::app::map::TileKey& key, const QString& reason)

Emitted when a download fails: a network or HTTP error, a timeout, or a reply that is not an image.

Nothing is cached for the tile. It is not requested again before its retry delay has passed, and never again when the server answered HTTP 404 or 410. Not emitted for a download aborted by set_online, clear or set_url_template.

Parameters

Name Type Description
key const nmeasim::app::map::TileKey& Tile that could not be downloaded.
reason const QString& Error text of the network reply, or the translated "not an image" when the body could not be decoded.

Declared in src/app/map/tile_cache.hpp:180

Private member functions

path_of()

QString path_of(const TileKey& key) const

Returns the file a tile is stored in on disk.

Parameters

Name Type Description
key const TileKey& Tile to locate.

Returns QString: <directory>/<zoom>/<x>/<y>.png, whether or not the file exists.

Declared in src/app/map/tile_cache.hpp:187 · defined in src/app/map/tile_cache.cpp:108

enqueue()

void enqueue(const TileKey& key)

Queues the download of a tile unless it is already queued or running, then starts downloads while fewer than four are running.

Parameters

Name Type Description
key const TileKey& Tile to download.

Declared in src/app/map/tile_cache.hpp:197 · defined in src/app/map/tile_cache.cpp:159

start_next()

void start_next()

Starts queued downloads, oldest first, until four are running or the queue is empty.

Declared in src/app/map/tile_cache.hpp:199 · defined in src/app/map/tile_cache.cpp:169

finish()

void finish(const TileKey& key, QNetworkReply* reply)

Handles a finished download: caches the tile on disk and in memory, emits tile_ready, or records the failure and emits tile_failed, and starts the next queued download.

A failure to write the file is ignored; the tile is then cached in memory only.

Parameters

Name Type Description
key const TileKey& Tile the reply belongs to.
reply QNetworkReply* Finished reply, owned by network_; its deletion is scheduled with deleteLater.

Declared in src/app/map/tile_cache.hpp:209 · defined in src/app/map/tile_cache.cpp:187

record_failure()

void record_failure(const QString& id, bool permanent)

Remembers that a tile failed to download and when it may be requested again.

Parameters

Name Type Description
id const QString& memory_key of the tile.
permanent bool true when the server reported the tile as not found, which is never retried; false to retry after the tile's next retry delay.

Declared in src/app/map/tile_cache.hpp:215 · defined in src/app/map/tile_cache.cpp:222

may_request()

bool may_request(const QString& id) const

Returns whether a tile may be queued for download now.

Parameters

Name Type Description
id const QString& memory_key of the tile.

Returns bool: false while the tile's retry delay runs and for a tile reported as not found; true otherwise.

Declared in src/app/map/tile_cache.hpp:221 · defined in src/app/map/tile_cache.cpp:234

abort_running()

void abort_running()

Aborts every running download without emitting a signal; the queued downloads stay.

The aborted tiles are neither cached nor recorded as failed, so the next tile call for one of them queues it again.

Declared in src/app/map/tile_cache.hpp:226 · defined in src/app/map/tile_cache.cpp:96

Private static member functions

memory_key()

static QString memory_key(const TileKey& key)

Returns the name of a tile in the memory cache and the download bookkeeping.

Parameters

Name Type Description
key const TileKey& Tile to name.

Returns QString: <zoom>/<x>/<y>.

Declared in src/app/map/tile_cache.hpp:192 · defined in src/app/map/tile_cache.cpp:112

Private data members

directory_

QString directory_

Root directory of the on-disk cache.

Declared in src/app/map/tile_cache.hpp:239

url_template_

QString url_template_

Tile server URL with {z}, {x} and {y} placeholders; never empty.

Declared in src/app/map/tile_cache.hpp:241

user_agent_

QString user_agent_

Value of the User-Agent header sent with every request.

Declared in src/app/map/tile_cache.hpp:243

online_

bool online_{true}

Whether missing tiles are downloaded; false serves the disk cache only.

Declared in src/app/map/tile_cache.hpp:245

memory_

QCache<QString, QPixmap> memory_

Decoded tiles by memory_key, at most 512, evicting the least recently used.

Declared in src/app/map/tile_cache.hpp:247

network_

QNetworkAccessManager network_

Network access for the downloads, owned by the cache.

Declared in src/app/map/tile_cache.hpp:249

queued_

QSet<QString> queued_

memory_key of every tile queued or running, so that a tile is requested only once at a time.

Declared in src/app/map/tile_cache.hpp:252

queue_

std::deque<TileKey> queue_

Tiles waiting for a download slot, oldest first.

Declared in src/app/map/tile_cache.hpp:254

running_

QHash<QString, QNetworkReply *> running_

Running downloads by memory_key, at most four; the replies are owned by network_.

Declared in src/app/map/tile_cache.hpp:256

failures_

QHash<QString, Failure> failures_

Failed downloads by memory_key, kept for the lifetime of the cache or until the tile server changes.

Declared in src/app/map/tile_cache.hpp:259

retry_delay_

std::chrono::milliseconds retry_delay_{std::chrono::seconds{30}}

Delay before a tile is requested again after its first failure.

Declared in src/app/map/tile_cache.hpp:261