Leaflet TileLayer subclass which caches to local filesystem, for Cordova/Phonegap

Includes a test/demo application for Cordova/Phonegap, walking through the basics. See its own README file.


See test/www/ for a functional application as well as JavaScript source code.

A basic example as as follows:

    BASE = L.tileLayerCordova('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        // these options are perfectly ordinary L.TileLayer options
        maxZoom: 18,
        attribution: '&copy; <a href="http://www.openstreetmap.org/copyright/">OpenStreetMap contributors</a>',
        // these are specific to L.TileLayer.Cordova and mostly specify where to store the tiles on disk
        folder: 'LTileLayerCordovaExample',
        name:   'example',
        debug:   true

    // calculate a tile pyramid starting at a lat/lon and going down to a stated range of zoom levels
    var tile_list = BASE.calculateXYZListFromPyramid(LAT, LNG, CACHE_ZOOM_MIN, CACHE_ZOOM_MAX);
        // 1st param: a list of XYZ objects indicating tiles to download
        // 2nd param: overwrite existing tiles on disk?
        // if no then a tile already on disk will be kept, which can be a big time saver
        // 3rd param: progress callback
        // receives the number of tiles downloaded and the number of tiles total
        // caller can calculate a percentage, update progress bar, etc.
        // Cancel: if the progress callback returns false (not null or undefined, but false)
        // then BASE.downloadXYZList() interprets that as a cancel order and will cease downloading tiles
        // great for a cancel button!
        function (done,total) {
            var percent = Math.round(100 * done / total);
            status_block.innerHTML = done  + " / " + total + " = " + percent + "%";
        // 4th param: complete callback
        // no parameters are given, but we know we're done!
        function () {
            // for this demo, on success we use another L.TileLayer.Cordova feature and show the disk usage!
            BASE.getDiskUsage(function (filecount,bytes) {
                var kilobytes = Math.round( bytes / 1024 );
                status_block.innerHTML = "Done" + "<br/>" + filecount + " files" + "<br/>" + kilobytes + " kB";
        // 5th param: error callback
        // parameter is the error message string
        function (error) {
            alert("Failed\nError code: " + error.code);

When running under Cordova/Phonegap this tile layer will behave much as usual, but has special behaviors such as the ability to cache sets of tiles, then to switch between "online mode" and "offline mode"

Constructor and Options

In Leaflet tradition, there is a constructor for use with new and also a utility function. They have an identical outcome: var layer = new L.TileLayer.Cordova(url,options) var layer = L.tileLayerCordova(url,options)

Most options are passed through to L.TileLayer and will be supported as is typical. This would include maxZoom, attributions, TMS, the {x}{y}{z}{s} markups in the IURL template, and so on. In addition, these config options are supported:

The constructor and utility function both support an optional success_callback. This will be called when all time-intensive filesystem activity is complete. Useful if you want to update a status indicator when the tilelayer has finished initializing. For example, if you want to call getDiskUsage() immediately in order to display the info to the user, that method should be called within this success_callback.

Cache Folders and TileLayer Names

Multiple L.TileLayer.Cordova instances may share the same folder. Cache management such as emptyCache() and getDiskUsage() are keyed by the folder, so it's important to understand these interactions.

Multiple L.TileLayer.Cordova instances may share the same folder, albeit with different name settings. In this scenario, calling getDiskUsage() on either layer would report a pooled usage... and calling emptyCache() on either layer would empty tiles for both layers. Thus, the specific wording in the documentation for those methods about the cache folder.

This is for the best: a typical use case would have all of your tiles in one folder, and you would want to view total usage and empty the entire cache for your application -- preferably without writing callback-within-callback to iterate over every layer in your app.

If you want your two layers to be separate, with separate usage counts and separate emptyCache() behaviors, then assign them to separate folders.

Methods - Toggling State

Methods - Determining State

Methods - Caching and Calculations

Much of this is based on the concept of xyz objects An XYZ object is simply a JavaScript object with the attributes x, y, and z used to describe the ordinates of a tile. Combined with the layer's URL template you provided in the constructor, or with the offline filesystem URL generated internally, an XYZ can be used to cmpose the URL of a specific tile in both offline state and online state.

Methods - Cache Management

See also: Cache Folders and TileLayer Names