Created
October 27, 2011 11:37
-
-
Save unxed/1319325 to your computer and use it in GitHub Desktop.
FileSystem API-based cache for Kothic-JS - v.0.03
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem; | |
BlobBuilder = window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder; | |
Object.size = function(obj) { | |
var size = 0, key; | |
for (key in obj) { | |
if (obj.hasOwnProperty(key)) size++; | |
} | |
return size; | |
}; | |
function base64pngToBin(str) | |
{ | |
var bin = window.atob(str.substr(22)); | |
return strToArrBuf(bin); | |
} | |
function strToArrBuf(str) | |
{ | |
arr = []; | |
for (var i=0; i<str.length;i++) { | |
arr.push(str.charCodeAt(i)); | |
} | |
return new Uint8Array( arr ).buffer; | |
} | |
if (typeof(window.requestFileSystem) != 'undefined') | |
{ | |
window.requestFileSystem(TEMPORARY, 1024 * 1024 * 128, onInitFs, errorHandler); | |
} | |
function onInitFs(fs_) { | |
window.fs = fs_; | |
} | |
function errorHandler(e) { | |
var msg = ''; | |
switch (e.code) { | |
case FileError.QUOTA_EXCEEDED_ERR: | |
msg = 'QUOTA_EXCEEDED_ERR'; | |
break; | |
case FileError.NOT_FOUND_ERR: | |
msg = 'NOT_FOUND_ERR'; | |
break; | |
case FileError.SECURITY_ERR: | |
msg = 'SECURITY_ERR'; | |
break; | |
case FileError.INVALID_MODIFICATION_ERR: | |
msg = 'INVALID_MODIFICATION_ERR'; | |
break; | |
case FileError.INVALID_STATE_ERR: | |
msg = 'INVALID_STATE_ERR'; | |
break; | |
default: | |
msg = 'Unknown Error'; | |
break; | |
}; | |
console.log('Error: ' + msg); | |
} | |
L.TileLayer.Kothic = L.TileLayer.Canvas.extend({ | |
options: { | |
tileSize: 256 * 4, | |
zoomOffset: 2, | |
minZoom: 2, | |
maxZoom: 22, | |
updateWhenIdle: true, | |
unloadInvisibleTiles: true, | |
attribution: 'Map data © 2011 OpenStreetMap contributors, Rendering by <a href="http://github.com/kothic/kothic-js">Kothic JS</a>', | |
async: true, | |
buffered: true | |
}, | |
initialize: function(options) { | |
L.Util.setOptions(this, options); | |
this._canvases = {}; | |
this._debugMessages = []; | |
var layer = this; | |
window.onKothicDataResponse = L.Util.bind(this._onKothicDataResponse, this); | |
}, | |
saveToCache: function(canvas, zoom, x, y) | |
{ | |
if ((typeof(fs) != 'undefined') && (typeof(window.requestFileSystem) != 'undefined')) | |
{ | |
// we now have correct filesystem object to use for cache | |
fs.root.getFile(x + '_' + y + '_' + zoom + '.png', {create: true}, function(fileEntry) { | |
console.log('saving to cache: '+fileEntry.fullPath); | |
// Create a FileWriter object for our FileEntry. | |
fileEntry.createWriter(function(fileWriter) { | |
fileWriter.seek(0); // Start write position at 0. | |
var bb = new BlobBuilder(); | |
bb.append(base64pngToBin(canvas.toDataURL("image/png"))); | |
fileWriter.write(bb.getBlob('image/png')); | |
bb = null; | |
console.log('saved to cache: '+fileEntry.fullPath); | |
}, errorHandler); | |
}, errorHandler); | |
} | |
}, | |
_onKothicDataResponse: function(data, zoom, x, y) { | |
var key = [zoom, x, y].join('/'), | |
canvas = this._canvases[key], | |
buffered = this.options.buffered, | |
zoomOffset = this.options.zoomOffset, | |
layer = this; | |
function onRenderComplete(debugInfo) { | |
layer.tileDrawn(canvas); | |
layer.saveToCache(canvas, zoom, x, y); | |
// TODO move this logic outside | |
// var debugStr = layer.getDebugStr(debugInfo, x, y, zoom); | |
// layer._debugMessages.push(debugStr); | |
// temporary disable debug messages | |
} | |
Kothic.render(canvas, data, zoom + zoomOffset, layer._additionalStyle, onRenderComplete, buffered); | |
delete this._canvases[key]; | |
}, | |
getDebugStr: function(debugInfo, x, y, zoom) { | |
return '<b>tile ' + x + ':' + y + ':' + zoom + '</b><br />' + | |
'<table><tr><td>' + debugInfo.layersStyled + ' ms</td><td>layers styled</td></tr>' + | |
'<tr><td>' + debugInfo.mapRendered + ' ms</td><td>map rendered</td></tr>' + | |
'<tr><td>' + debugInfo.iconsAndTextRendered + ' ms</td><td>icons/text rendered</td></tr>' + | |
'<tr><td>' + debugInfo.total + ' ms</td><td>total</td></tr></table>'; | |
}, | |
getDebugMessages: function() { | |
return this._debugMessages; | |
}, | |
drawTile: function(canvas, tilePoint, zoom) { | |
console.log('debug: _canvases size: '+Object.size(this._canvases)); | |
var zoomOffset = this.options.zoomOffset, | |
key = [(zoom - zoomOffset), tilePoint.x, tilePoint.y].join('/'), | |
path = '/' + [tilePoint.x, tilePoint.y, (zoom - zoomOffset)].join('_') + '.png'; | |
console.log('seeking cache for: '+path); | |
var url = 'http://2g0.ru/map/kothic/tileprxy.php?z=' + (zoom - zoomOffset) + '&x=' + tilePoint.x + '&y=' + tilePoint.y; | |
var layer = this; | |
if ((typeof(fs) != 'undefined') && (typeof(window.requestFileSystem) != 'undefined')) | |
{ | |
fs.root.getFile(path, {}, function(fileEntry) { | |
var cached_img = new Image(); | |
cached_img.src = fileEntry.toURL();; | |
cached_img.onload = function () { | |
canvas.getContext('2d').drawImage(cached_img, 0, 0); | |
layer.tileDrawn(canvas); | |
console.log('shown from cache: '+path); | |
} | |
}, function(e) { | |
layer._canvases[key] = canvas; | |
layer._loadScript(url); | |
errorHandler(e); | |
console.log('requesting from server: '+path); | |
} ); | |
} else { | |
layer._canvases[key] = canvas; | |
layer._loadScript(url); | |
} | |
}, | |
setAdditionalStyle: function(fn) { | |
this._additionalStyle = fn; | |
// TODO implement layer.redraw() in Leaflet | |
if (this._map && this._map._container) { | |
this._reset(); | |
this._update(); | |
} | |
}, | |
_loadScript: function(url) { | |
var script = document.createElement('script'); | |
script.src = url; | |
script.charset = 'utf-8'; | |
document.getElementsByTagName('head')[0].appendChild(script); | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment