ebodin

Cache tiles in WebSQL instead of LocalStorage?

Discussion created by ebodin on Jan 27, 2012
Latest reply on Apr 2, 2012 by ebodin
I have an html5 application caching tiles from a tiled map service layer in LocalStorage (originally from this sample: http://help.arcgis.com/en/webapi/javascript/arcgis/help/jssamples_start.htm), which works fine.  The problem is the size limit; I just can't cache enough tiles.

So now I'm trying to use WebSQL (in which you can increase the database size).  I can store the tiles in the database, but the problem arises when I try to retrieve them.  WebSQL transactions are asynchronous, so when I issue the statement to retrieve the tile from the database, the getTileUrl function continues and returns nothing (a gray tile) without waiting for the query to return.

Is there some way to make the process wait for the readTransaction function below to return a value?

    dojo.extend(esri.layers.ArcGISTiledMapServiceLayer, {
        getTileUrl: function (level, row, col) {
            var url = tiledLayerSource + "/tile/" + level + "/" + row + "/" + col;
            url = window.location.protocol + '//' + window.location.host + proxyPage + "?" + url;
            var result;
            if (usingWebSQL) {
                // the next statement is asynchronous, so this approach fails
                dbMapCache.readTransaction(function (t) {
                    var s = 'select IMAGE FROM TILES where url = ?';
                    t.executeSql(s, [url], function (t, rs) {
                        if (rs && rs.rows.length > 0) {
                            var r = rs.rows.item(0);
                            result = "data:image;base64," + r.IMAGE;
                        }
                        else {
                            console.log('query returned nothing, pass url and load tile');
                            ioWorker.postMessage([url]);
                            result = url;
                        }
                    });
                });
            }
            else {
                // this approach uses localStorage, and it works
                if (localStorage.getItem(url) !== null) {
                    console.log("in local storage");
                    result = "data:image;base64," + localStorage.getItem(url);
                } else {
                    if (keepCaching) {
                        console.log("not in local storage, pass url and load tile");
                        ioWorker.postMessage([url]);
                    }
                    result = url;
                }
            }
            return result;
        }
    });

Outcomes