Files
openlayers/examples/offline-storage.js
ahocevar f18ac9911b Adding CacheRead and CacheWrite controls.
These controls read from and write to the browser's offline storage. Example with a seeding tool included.
2012-03-08 14:18:44 +01:00

183 lines
6.3 KiB
JavaScript

var map, cacheWrite, cacheRead1, cacheRead2;
function init(){
map = new OpenLayers.Map({
div: "map",
projection: "EPSG:900913",
layers: [new OpenLayers.Layer.OSM("OpenStreetMap (CORS)", null, {
eventListeners: {
loadend: updateLayerInfo,
tileloaded: updateTileInfo,
tileerror: updateTileInfo
}
}),
new OpenLayers.Layer.WMS("OSGeo (same origin - proxied)", "http://vmap0.tiles.osgeo.org/wms/vmap0", {
layers: "basic"
}, {
eventListeners: {
tileloadstart: function(evt) {
// send requests through proxy
evt.tile.url = "proxy.cgi?url=" + encodeURIComponent(evt.tile.url);
},
loadend: updateLayerInfo,
tileloaded: updateTileInfo
}
})
],
center: [0,0],
zoom: 1
});
cacheWrite = new OpenLayers.Control.CacheWrite({
imageFormat: "image/jpeg",
eventListeners: {
cachefull: function() {
status.innerHTML = "Cache full.";
cacheFull = true;
}
}
});
// try cache before loading from remote resource
cacheRead1 = new OpenLayers.Control.CacheRead({
eventListeners: {
activate: function() {
cacheRead2.deactivate();
}
}
});
// try loading from remote resource and fall back to cache
cacheRead2 = new OpenLayers.Control.CacheRead({
autoActivate: false,
fetchEvent: "tileerror",
eventListeners: {
activate: function() {
cacheRead1.deactivate();
}
}
});
var layerSwitcher = new OpenLayers.Control.LayerSwitcher();
map.addControls([cacheWrite, cacheRead1, cacheRead2, layerSwitcher]);
layerSwitcher.maximizeControl();
// add UI and behavior
var status = document.getElementById("status"),
hits = document.getElementById("hits"),
previousCount = -1,
cacheHits = 0,
cacheFull = false;
updateLayerInfo();
var read = document.getElementById("read");
read.checked = true;
read.onclick = toggleRead;
var write = document.getElementById("write");
write.checked = false;
write.onclick = toggleWrite;
document.getElementById("clear").onclick = clearCache;
var tileloadstart = document.getElementById("tileloadstart");
tileloadstart.checked = "checked";
tileloadstart.onclick = setType;
document.getElementById("tileerror").onclick = setType;
document.getElementById("seed").onclick = seedCache;
// update the number of cached tiles and detect local storage support
function updateLayerInfo(evt) {
if (window.localStorage) {
if (previousCount !== localStorage.length) {
status.innerHTML = localStorage.length + " entries in cache.";
}
previousCount = localStorage.length;
} else {
status.innerHTML = "Local storage not supported. Try a different browser.";
}
}
// update the number of cache hits and detect missing CORS support
function updateTileInfo(evt) {
if (cacheWrite.active) {
try {
var canvasContext = evt.tile.getCanvasContext();
if (canvasContext) {
// will throw an exception if CORS image requests are not supported
canvasContext.canvas.toDataURL();
} else {
status.innerHTML = "Canvas not supported. Try a different browser.";
}
} catch(e) {
status.innerHTML = "CORS image requests not supported. Try a different layer.";
}
}
if (evt.tile.url.substr(0, 5) === "data:") {
cacheHits++;
}
hits.innerHTML = cacheHits + " cache hits.";
}
// turn the cacheRead controls on and off
function toggleRead() {
if (!this.checked) {
cacheRead1.deactivate();
cacheRead2.deactivate();
} else {
setType();
}
}
// turn the cacheWrite control on and off
function toggleWrite() {
cacheWrite[cacheWrite.active ? "deactivate" : "activate"]();
}
// clear all tiles from the cache
function clearCache() {
OpenLayers.Control.CacheWrite.clearCache();
cacheFull = false;
updateLayerInfo();
}
// activate the cacheRead control that matches the desired fetch strategy
function setType() {
if (tileloadstart.checked) {
cacheRead1.activate();
} else {
cacheRead2.activate();
}
}
// seed the cache
function seedCache() {
var zoom = map.getZoom();
var extent = map.getExtent();
var center = map.getCenter();
var active = cacheWrite.active;
var tileWidth = map.baseLayer.tileSize.w;
var layer = map.baseLayer;
var buffer = layer.buffer;
// make sure the next setCenter triggers a load
map.zoomTo(zoom === layer.numZoomLevels-1 ? zoom - 1 : zoom + 1);
// turn on cache writing
cacheWrite.activate();
// turn off cache reading
cacheRead1.deactivate();
cacheRead2.deactivate();
layer.events.register("loadend", this, function next() {
var nextZoom = map.getZoom() + 1;
var extentWidth = extent.getWidth() / map.getResolutionForZoom(nextZoom);
// adjust the layer's buffer size so we don't have to pan
layer.buffer = Math.ceil((extentWidth / tileWidth - map.getSize().w / tileWidth) / 2);
map.zoomIn();
if (cacheFull || nextZoom === layer.numZoomLevels-1) {
// we're done - restore previous settings
layer.events.unregister("loadend", this, next);
layer.buffer = buffer;
map.setCenter(center, zoom);
if (!active) {
cacheWrite.deactivate();
}
if (read.checked) {
setType();
}
}
});
// start seeding
map.setCenter(center, zoom);
}
}