Quick start
The example below, running in the Mappia calculator - click it to run it live. Full-size picture
- Run it
Click the picture: the map opens right here and runs the example. Nothing is saved, and nothing to install.
- Try it
- Press “How many tiles is this view?”: the label counts the tiles of this view over three zoom levels.
- Pan or zoom the map and press it again: the estimate follows the current view.
- Use
zoom + 4instead ofzoom + 2inestimate: the count grows about fourfold per extra level.
- Make it yours
Copy the query, change it - the key parameters are below - and run it again in the playground, or paste it into the Mappia editor to save it as your map.
Key parameters
| Parameter | Example | What it does |
|---|---|---|
getCacheableLayers | ExtjsUtils.OFFLINE.getCacheableLayers() | Lists the layers on the map whose tiles can be saved. Pass the list, or part of it, as layers. |
estimateTileCountForLayers | ExtjsUtils.OFFLINE.estimateTileCountForLayers(map.getExtent(), 10, 13, layers) | Counts the tiles an area would need, without downloading anything. Check it before every download. |
downloadArea | ExtjsUtils.OFFLINE.downloadArea({ name: "Farm 4711", extent: map.getExtent(), zoomMin: 10, zoomMax: 13 }) | Downloads the tiles of an extent and zoom range into the browser; resolves with the area’s record. |
setServingPolicy | ExtjsUtils.OFFLINE.setServingPolicy({ mode: "CacheOnly" }) | Chooses whether tiles come from the download or the network. The map reloads its tiles at once. |
listAreas | ExtjsUtils.OFFLINE.listAreas() | Resolves with every area saved in this browser: id, name, status, tile count and size. |
deleteArea | ExtjsUtils.OFFLINE.deleteArea(area.id) | Removes an area’s tiles and record from the browser. |
Every parameter, with its type and default, is in the reference at the end of this page.
Complete example
The query 26 lines · runs as is
// Offline areas: ExtjsUtils.OFFLINE downloads an area's tiles for use without a connection.
// Estimating first costs nothing - it only counts the tiles of the chosen layers and zooms.
[
{
title: "Offline areas",
name: "CSR:estados",
source: "calculate",
opacity: 0.5,
visibility: true,
paramsButtonConfig: [{ type: "query", pressed: true }],
descriptionHtml:
"{{button|id=estimate_area|text=How many tiles is this view?|handler=estimate}}" +
"{{label|id=estimate_label|text=Press the button to estimate.}}",
functions: {
estimate: function () {
var map = ExtjsUtils.JS.getMap();
var zoom = map.getZoom();
var layers = ExtjsUtils.OFFLINE.getCacheableLayers();
var tiles = ExtjsUtils.OFFLINE.estimateTileCountForLayers(map.getExtent(), zoom, zoom + 2, layers);
Ext.getCmp("estimate_label").setText(
"This view at zoom " + zoom + "-" + (zoom + 2) + ": " + tiles + " tiles for " + layers.length + " layer(s)."
);
},
},
},
];Customize it
The steps
- Choose the layers:
getCacheableLayers()lists the ones that can be saved. - Estimate:
estimateTileCountForLayers(extent, zoomMin, zoomMax, layers)counts the tiles, andcheckStorageQuota()tells how much space the browser grants. - Download:
downloadArea({...})saves the tiles in the browser.
var map = ExtjsUtils.JS.getMap();
ExtjsUtils.OFFLINE.downloadArea({
name: "Farm 4711",
extent: map.getExtent(),
zoomMin: map.getZoom(),
zoomMax: map.getZoom() + 3,
layers: ExtjsUtils.OFFLINE.getCacheableLayers(),
onProgress: function (p) { console.log(p.done + " / " + p.total); },
}).then(function (area) {
console.log(area.status, area.tileCount + " tiles");
});
Run this from a button handler or another callback, after the map has loaded.
Which layers can be saved
Tiled catalogue maps and tile basemaps such as OpenStreetMap and XYZ layers. Calculated layers that use an operation cannot, because their images depend on the view rather than on a tile grid, and neither can Google or Bing basemaps, whose terms forbid it. Call getCacheableLayers after the query’s layers are on the map; in code that runs right after loading, wait for ExtjsUtils.OFFLINE.whenLayersReady() first.
Size limits
Each extra zoom level multiplies the tiles by about four. An area may hold at most 20,000 tiles: above that, downloadArea refuses with “Area too large” before downloading anything. Pass maxTiles to change the limit for one call.
How saved tiles are served
A policy chosen by the page; changing it reloads the tiles on screen, so the difference shows at once:
mode | Behaviour |
|---|---|
CacheFirst (default) | The saved tile if there is one, the network otherwise |
NetworkFirst | The live tile; the saved one only when the network fails |
CacheOnly | Only saved tiles - never the network |
NetworkOnly | Only the network - ignore saved tiles |
When a tile at the current zoom was not saved, the nearest coarser saved zoom is cropped to fill it, so zooming past the saved range blurs instead of leaving holes.
Managing areas
- Download again with the same
idto resume or extend an area: tiles already saved are not fetched again. - An aborted download, or one with failed tiles, ends with status
partial. listAreas()anddeleteArea(id)list and remove areas.exportAreaAsZip(id)packs an area into one file, andimportAreaFromZip(blob)rebuilds it on another device without downloading the tiles again.
Check that it really works offline
Saved tiles are served by the browser’s service worker, which only takes control of a page from its next load. verifyAreaServed(id) re-requests a sample of an area’s tiles and reports whether they really came from the download.