From 90069b32ec2571b0aa448dc7199744a0074e0ffc Mon Sep 17 00:00:00 2001 From: Andy Gup Date: Tue, 13 Sep 2016 19:09:18 -0600 Subject: [PATCH 1/4] added base64String lib, updated license.md --- lib/tiles/LICENSE.md | 14 +- lib/tiles/base64string.js | 285 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 293 insertions(+), 6 deletions(-) create mode 100644 lib/tiles/base64string.js diff --git a/lib/tiles/LICENSE.md b/lib/tiles/LICENSE.md index 5300273b..d2eadabf 100644 --- a/lib/tiles/LICENSE.md +++ b/lib/tiles/LICENSE.md @@ -1,11 +1,16 @@ +## base64String.js +License for base64String.js is WTFPL, Version 2, http://www.wtfpl.net/ and provided courtesy and copyright of Pieroxy . + + +## FileSaver.js + License for FileSaver.js This software is licensed under the MIT/X11 license. MIT/X11 license ---------------- -Copyright © 2011 [Eli Grey][1]. +Copyright © 2011 [Eli Grey] http://eligrey.com Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation @@ -26,7 +31,4 @@ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - - - [1]: http://eligrey.com \ No newline at end of file +OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/lib/tiles/base64string.js b/lib/tiles/base64string.js new file mode 100644 index 00000000..b35029d1 --- /dev/null +++ b/lib/tiles/base64string.js @@ -0,0 +1,285 @@ +// Copyright (c) 2013 Pieroxy +// This work is free. You can redistribute it and/or modify it +// under the terms of the WTFPL, Version 2 +// For more information see LICENSE.txt or http://www.wtfpl.net/ +// +// This lib is part of the lz-string project. +// For more information, the home page: +// http://pieroxy.net/blog/pages/lz-string/index.html +// +// Base64 compression / decompression for already compressed content (gif, png, jpg, mp3, ...) +// version 1.4.1 +O.esri.Tiles.Base64String = { + + compressToUTF16 : function (input) { + var output = [], + i,c, + current, + status = 0; + + input = this.compress(input); + + for (i=0 ; i> 1)+32)); + current = (c & 1) << 14; + break; + case 1: + output.push(String.fromCharCode((current + (c >> 2))+32)); + current = (c & 3) << 13; + break; + case 2: + output.push(String.fromCharCode((current + (c >> 3))+32)); + current = (c & 7) << 12; + break; + case 3: + output.push(String.fromCharCode((current + (c >> 4))+32)); + current = (c & 15) << 11; + break; + case 4: + output.push(String.fromCharCode((current + (c >> 5))+32)); + current = (c & 31) << 10; + break; + case 5: + output.push(String.fromCharCode((current + (c >> 6))+32)); + current = (c & 63) << 9; + break; + case 6: + output.push(String.fromCharCode((current + (c >> 7))+32)); + current = (c & 127) << 8; + break; + case 7: + output.push(String.fromCharCode((current + (c >> 8))+32)); + current = (c & 255) << 7; + break; + case 8: + output.push(String.fromCharCode((current + (c >> 9))+32)); + current = (c & 511) << 6; + break; + case 9: + output.push(String.fromCharCode((current + (c >> 10))+32)); + current = (c & 1023) << 5; + break; + case 10: + output.push(String.fromCharCode((current + (c >> 11))+32)); + current = (c & 2047) << 4; + break; + case 11: + output.push(String.fromCharCode((current + (c >> 12))+32)); + current = (c & 4095) << 3; + break; + case 12: + output.push(String.fromCharCode((current + (c >> 13))+32)); + current = (c & 8191) << 2; + break; + case 13: + output.push(String.fromCharCode((current + (c >> 14))+32)); + current = (c & 16383) << 1; + break; + case 14: + output.push(String.fromCharCode((current + (c >> 15))+32, (c & 32767)+32)); + status = 0; + break; + } + } + output.push(String.fromCharCode(current + 32)); + return output.join(''); + }, + + + decompressFromUTF16 : function (input) { + var output = [], + current,c, + status=0, + i = 0; + + while (i < input.length) { + c = input.charCodeAt(i) - 32; + + switch (status++) { + case 0: + current = c << 1; + break; + case 1: + output.push(String.fromCharCode(current | (c >> 14))); + current = (c&16383) << 2; + break; + case 2: + output.push(String.fromCharCode(current | (c >> 13))); + current = (c&8191) << 3; + break; + case 3: + output.push(String.fromCharCode(current | (c >> 12))); + current = (c&4095) << 4; + break; + case 4: + output.push(String.fromCharCode(current | (c >> 11))); + current = (c&2047) << 5; + break; + case 5: + output.push(String.fromCharCode(current | (c >> 10))); + current = (c&1023) << 6; + break; + case 6: + output.push(String.fromCharCode(current | (c >> 9))); + current = (c&511) << 7; + break; + case 7: + output.push(String.fromCharCode(current | (c >> 8))); + current = (c&255) << 8; + break; + case 8: + output.push(String.fromCharCode(current | (c >> 7))); + current = (c&127) << 9; + break; + case 9: + output.push(String.fromCharCode(current | (c >> 6))); + current = (c&63) << 10; + break; + case 10: + output.push(String.fromCharCode(current | (c >> 5))); + current = (c&31) << 11; + break; + case 11: + output.push(String.fromCharCode(current | (c >> 4))); + current = (c&15) << 12; + break; + case 12: + output.push(String.fromCharCode(current | (c >> 3))); + current = (c&7) << 13; + break; + case 13: + output.push(String.fromCharCode(current | (c >> 2))); + current = (c&3) << 14; + break; + case 14: + output.push(String.fromCharCode(current | (c >> 1))); + current = (c&1) << 15; + break; + case 15: + output.push(String.fromCharCode(current | c)); + status=0; + break; + } + + + i++; + } + + return this.decompress(output.join('')); + //return output; + + }, + + + // private property + _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", + + decompress : function (input) { + var output = []; + var chr1, chr2, chr3, enc1, enc2, enc3, enc4; + var i = 1; + var odd = input.charCodeAt(0) >> 8; + + while (i < input.length*2 && (i < input.length*2-1 || odd==0)) { + + if (i%2==0) { + chr1 = input.charCodeAt(i/2) >> 8; + chr2 = input.charCodeAt(i/2) & 255; + if (i/2+1 < input.length) + chr3 = input.charCodeAt(i/2+1) >> 8; + else + chr3 = NaN; + } else { + chr1 = input.charCodeAt((i-1)/2) & 255; + if ((i+1)/2 < input.length) { + chr2 = input.charCodeAt((i+1)/2) >> 8; + chr3 = input.charCodeAt((i+1)/2) & 255; + } else + chr2=chr3=NaN; + } + i+=3; + + enc1 = chr1 >> 2; + enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); + enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); + enc4 = chr3 & 63; + + if (isNaN(chr2) || (i==input.length*2+1 && odd)) { + enc3 = enc4 = 64; + } else if (isNaN(chr3) || (i==input.length*2 && odd)) { + enc4 = 64; + } + + output.push(this._keyStr.charAt(enc1)); + output.push(this._keyStr.charAt(enc2)); + output.push(this._keyStr.charAt(enc3)); + output.push(this._keyStr.charAt(enc4)); + } + + return output.join(''); + }, + + compress : function (input) { + var output = [], + ol = 1, + output_, + chr1, chr2, chr3, + enc1, enc2, enc3, enc4, + i = 0, flush=false; + + input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); + + while (i < input.length) { + + enc1 = this._keyStr.indexOf(input.charAt(i++)); + enc2 = this._keyStr.indexOf(input.charAt(i++)); + enc3 = this._keyStr.indexOf(input.charAt(i++)); + enc4 = this._keyStr.indexOf(input.charAt(i++)); + + chr1 = (enc1 << 2) | (enc2 >> 4); + chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); + chr3 = ((enc3 & 3) << 6) | enc4; + + if (ol%2==0) { + output_ = chr1 << 8; + flush = true; + + if (enc3 != 64) { + output.push(String.fromCharCode(output_ | chr2)); + flush = false; + } + if (enc4 != 64) { + output_ = chr3 << 8; + flush = true; + } + } else { + output.push(String.fromCharCode(output_ | chr1)); + flush = false; + + if (enc3 != 64) { + output_ = chr2 << 8; + flush = true; + } + if (enc4 != 64) { + output.push(String.fromCharCode(output_ | chr3)); + flush = false; + } + } + ol+=3; + } + + if (flush) { + output.push(String.fromCharCode(output_)); + output = output.join(''); + output = String.fromCharCode(output.charCodeAt(0)|256) + output.substring(1); + } else { + output = output.join(''); + } + + return output; + + } +} From 6657ff4df0942c790c927b57102d920547727ee1 Mon Sep 17 00:00:00 2001 From: Andy Gup Date: Tue, 13 Sep 2016 19:11:40 -0600 Subject: [PATCH 2/4] display tile id on offline tile return --- lib/tiles/TilesCore.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tiles/TilesCore.js b/lib/tiles/TilesCore.js index a9f88b92..185542fc 100644 --- a/lib/tiles/TilesCore.js +++ b/lib/tiles/TilesCore.js @@ -18,7 +18,7 @@ O.esri.Tiles.TilesCore = function(){ */ this._getTiles = function(image,imageType,url,tileid,store,query,showBlankTiles){ store.retrieve(url, function(success, offlineTile) - { console.log("TILE RETURN " + success + ", " + offlineTile.url); + { console.log("TILE RETURN " + success + ", " + offlineTile.url + ", " + tileid); /* when the .getTileUrl() callback is triggered we replace the temporary URL originally returned by the data:image url */ // search for the img with src="void:"+level+"-"+row+"-"+col and replace with actual url image = query("img[src="+tileid+"]")[0]; From 98b8733b5b7aca55b9c6d9a07715c514fd4f1e2b Mon Sep 17 00:00:00 2001 From: Andy Gup Date: Tue, 13 Sep 2016 19:20:30 -0600 Subject: [PATCH 3/4] added jslint rules --- lib/tiles/base64string.js | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/lib/tiles/base64string.js b/lib/tiles/base64string.js index b35029d1..7a4e8630 100644 --- a/lib/tiles/base64string.js +++ b/lib/tiles/base64string.js @@ -9,6 +9,8 @@ // // Base64 compression / decompression for already compressed content (gif, png, jpg, mp3, ...) // version 1.4.1 + +/*jslint bitwise: true */ O.esri.Tiles.Base64String = { compressToUTF16 : function (input) { @@ -175,7 +177,7 @@ O.esri.Tiles.Base64String = { // private property - _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", + _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", // jshint ignore:line decompress : function (input) { var output = []; @@ -183,22 +185,25 @@ O.esri.Tiles.Base64String = { var i = 1; var odd = input.charCodeAt(0) >> 8; - while (i < input.length*2 && (i < input.length*2-1 || odd==0)) { + while (i < input.length*2 && (i < input.length*2-1 || odd===0)) { - if (i%2==0) { + if (i%2===0) { chr1 = input.charCodeAt(i/2) >> 8; chr2 = input.charCodeAt(i/2) & 255; - if (i/2+1 < input.length) - chr3 = input.charCodeAt(i/2+1) >> 8; - else + if (i/2+1 < input.length) { + chr3 = input.charCodeAt(i / 2 + 1) >> 8; + } + else { chr3 = NaN; + } } else { chr1 = input.charCodeAt((i-1)/2) & 255; if ((i+1)/2 < input.length) { chr2 = input.charCodeAt((i+1)/2) >> 8; chr3 = input.charCodeAt((i+1)/2) & 255; - } else - chr2=chr3=NaN; + } else { + chr2 = chr3 = NaN; + } } i+=3; @@ -230,7 +235,7 @@ O.esri.Tiles.Base64String = { enc1, enc2, enc3, enc4, i = 0, flush=false; - input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); + input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); // jshint ignore:line while (i < input.length) { @@ -243,7 +248,7 @@ O.esri.Tiles.Base64String = { chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); chr3 = ((enc3 & 3) << 6) | enc4; - if (ol%2==0) { + if (ol%2===0) { output_ = chr1 << 8; flush = true; @@ -282,4 +287,6 @@ O.esri.Tiles.Base64String = { return output; } -} +}; + +/*jslint bitwise: false */ From 037ed5666b818f4790a0e56bb33f94e3186a3559 Mon Sep 17 00:00:00 2001 From: Andy Gup Date: Tue, 13 Sep 2016 19:21:43 -0600 Subject: [PATCH 4/4] v3.4.0 - add tiles database compression --- CHANGELOG.md | 11 ++ Gruntfile.js | 3 + dist/offline-edit-advanced-src.js | 2 +- dist/offline-edit-basic-src.js | 2 +- dist/offline-tiles-advanced-min.js | 70 ++++++- dist/offline-tiles-advanced-src.js | 299 ++++++++++++++++++++++++++++- dist/offline-tiles-basic-min.js | 70 ++++++- dist/offline-tiles-basic-src.js | 299 ++++++++++++++++++++++++++++- dist/offline-tpk-min.js | 6 +- dist/offline-tpk-src.js | 4 +- lib/tiles/TilesStore.js | 2 + package.json | 2 +- samples/package.json | 2 +- 13 files changed, 755 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b9e6b4c5..45f8b27c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # offline-editor-js - Changelog +## Version 3.4.0 - September 13, 2016 + +Possible breaking changes. + +**Enhancements** +* Added base64 re-encoding to the tile database that results in a 2.7x (16/6) reduction in storage size. + +**Known Issues** +* Firefox v48.x is showing tiles as hidden when they should be visible. This issue existed at v3.3.2. + + ## Version 3.3.2 - August 24, 2016 No breaking changes. diff --git a/Gruntfile.js b/Gruntfile.js index 505a392e..72e505ee 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -33,6 +33,7 @@ module.exports = function(grunt) { 'lib/tiles/OfflineTilesNS.js', 'lib/tiles/TilesCore.js', 'lib/tiles/TilesStore.js', + 'lib/tiles/base64string.js', 'lib/tiles/tilingScheme.js', 'lib/tpk/autoCenterMap.js', 'lib/tpk/OfflineTpkNS.js', @@ -74,6 +75,7 @@ module.exports = function(grunt) { 'lib/tiles/OfflineTilesBasic.js', 'lib/tiles/OfflineTilesNS.js', 'lib/tiles/base64utils.js', + 'lib/tiles/base64string.js', 'lib/tiles/FileSaver.js', 'lib/tiles/TilesCore.js', 'lib/tiles/TilesStore.js', @@ -87,6 +89,7 @@ module.exports = function(grunt) { 'lib/tiles/OfflineTilesAdvanced.js', 'lib/tiles/OfflineTilesNS.js', 'lib/tiles/base64utils.js', + 'lib/tiles/base64string.js', 'lib/tiles/FileSaver.js', 'lib/tiles/TilesCore.js', 'lib/tiles/TilesStore.js', diff --git a/dist/offline-edit-advanced-src.js b/dist/offline-edit-advanced-src.js index eb953c22..cc5dd9e0 100644 --- a/dist/offline-edit-advanced-src.js +++ b/dist/offline-edit-advanced-src.js @@ -1,4 +1,4 @@ -/*! esri-offline-maps - v3.3.0 - 2016-07-12 +/*! esri-offline-maps - v3.4.0 - 2016-09-13 * Copyright (c) 2016 Environmental Systems Research Institute, Inc. * Apache License*/ // Configure offline/online detection diff --git a/dist/offline-edit-basic-src.js b/dist/offline-edit-basic-src.js index 3205403e..c38cd2c6 100644 --- a/dist/offline-edit-basic-src.js +++ b/dist/offline-edit-basic-src.js @@ -1,4 +1,4 @@ -/*! esri-offline-maps - v3.3.0 - 2016-07-12 +/*! esri-offline-maps - v3.4.0 - 2016-09-13 * Copyright (c) 2016 Environmental Systems Research Institute, Inc. * Apache License*/ // Configure offline/online detection diff --git a/dist/offline-tiles-advanced-min.js b/dist/offline-tiles-advanced-min.js index a94b1e23..dee7390c 100644 --- a/dist/offline-tiles-advanced-min.js +++ b/dist/offline-tiles-advanced-min.js @@ -30,7 +30,69 @@ return d<<16|65535&c},O.esri.Tiles.Base64Utils.stringToWord=function(a){for(var return d},O.esri.Tiles.Base64Utils.wordToString=function(a){for(var b=8,c=(1<e;e+=b)d.push(String.fromCharCode(a[e>>5]>>>e%32&c)) return d.join("")},O.esri.Tiles.Base64Utils.wordToHex=function(a){for(var b="0123456789abcdef",c=[],d=0,e=4*a.length;e>d;d++)c.push(b.charAt(a[d>>2]>>d%4*8+4&15)+b.charAt(a[d>>2]>>d%4*8&15)) return c.join("")},O.esri.Tiles.Base64Utils.wordToBase64=function(a){for(var b="=",c="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",d=[],e=0,f=4*a.length;f>e;e+=3)for(var g=(a[e>>2]>>8*(e%4)&255)<<16|(a[e+1>>2]>>8*((e+1)%4)&255)<<8|a[e+2>>2]>>8*((e+2)%4)&255,h=0;4>h;h++)8*e+6*h>32*a.length?d.push(b):d.push(c.charAt(g>>6*(3-h)&63)) -return d.join("")},O.esri.Tiles.saveAs=function(a){"use strict" +return d.join("")},O.esri.Tiles.Base64String={compressToUTF16:function(a){var b,c,d,e=[],f=0 +for(a=this.compress(a),b=0;b>1)+32)),d=(1&c)<<14 +break +case 1:e.push(String.fromCharCode(d+(c>>2)+32)),d=(3&c)<<13 +break +case 2:e.push(String.fromCharCode(d+(c>>3)+32)),d=(7&c)<<12 +break +case 3:e.push(String.fromCharCode(d+(c>>4)+32)),d=(15&c)<<11 +break +case 4:e.push(String.fromCharCode(d+(c>>5)+32)),d=(31&c)<<10 +break +case 5:e.push(String.fromCharCode(d+(c>>6)+32)),d=(63&c)<<9 +break +case 6:e.push(String.fromCharCode(d+(c>>7)+32)),d=(127&c)<<8 +break +case 7:e.push(String.fromCharCode(d+(c>>8)+32)),d=(255&c)<<7 +break +case 8:e.push(String.fromCharCode(d+(c>>9)+32)),d=(511&c)<<6 +break +case 9:e.push(String.fromCharCode(d+(c>>10)+32)),d=(1023&c)<<5 +break +case 10:e.push(String.fromCharCode(d+(c>>11)+32)),d=(2047&c)<<4 +break +case 11:e.push(String.fromCharCode(d+(c>>12)+32)),d=(4095&c)<<3 +break +case 12:e.push(String.fromCharCode(d+(c>>13)+32)),d=(8191&c)<<2 +break +case 13:e.push(String.fromCharCode(d+(c>>14)+32)),d=(16383&c)<<1 +break +case 14:e.push(String.fromCharCode(d+(c>>15)+32,(32767&c)+32)),f=0}return e.push(String.fromCharCode(d+32)),e.join("")},decompressFromUTF16:function(a){for(var b,c,d=[],e=0,f=0;f>14)),b=(16383&c)<<2 +break +case 2:d.push(String.fromCharCode(b|c>>13)),b=(8191&c)<<3 +break +case 3:d.push(String.fromCharCode(b|c>>12)),b=(4095&c)<<4 +break +case 4:d.push(String.fromCharCode(b|c>>11)),b=(2047&c)<<5 +break +case 5:d.push(String.fromCharCode(b|c>>10)),b=(1023&c)<<6 +break +case 6:d.push(String.fromCharCode(b|c>>9)),b=(511&c)<<7 +break +case 7:d.push(String.fromCharCode(b|c>>8)),b=(255&c)<<8 +break +case 8:d.push(String.fromCharCode(b|c>>7)),b=(127&c)<<9 +break +case 9:d.push(String.fromCharCode(b|c>>6)),b=(63&c)<<10 +break +case 10:d.push(String.fromCharCode(b|c>>5)),b=(31&c)<<11 +break +case 11:d.push(String.fromCharCode(b|c>>4)),b=(15&c)<<12 +break +case 12:d.push(String.fromCharCode(b|c>>3)),b=(7&c)<<13 +break +case 13:d.push(String.fromCharCode(b|c>>2)),b=(3&c)<<14 +break +case 14:d.push(String.fromCharCode(b|c>>1)),b=(1&c)<<15 +break +case 15:d.push(String.fromCharCode(b|c)),e=0}f++}return this.decompress(d.join(""))},_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",decompress:function(a){for(var b,c,d,e,f,g,h,i=[],j=1,k=a.charCodeAt(0)>>8;j<2*a.length&&(j<2*a.length-1||0===k);)j%2===0?(b=a.charCodeAt(j/2)>>8,c=255&a.charCodeAt(j/2),d=j/2+1>8:NaN):(b=255&a.charCodeAt((j-1)/2),(j+1)/2>8,d=255&a.charCodeAt((j+1)/2)):c=d=NaN),j+=3,e=b>>2,f=(3&b)<<4|c>>4,g=(15&c)<<2|d>>6,h=63&d,isNaN(c)||j==2*a.length+1&&k?g=h=64:(isNaN(d)||j==2*a.length&&k)&&(h=64),i.push(this._keyStr.charAt(e)),i.push(this._keyStr.charAt(f)),i.push(this._keyStr.charAt(g)),i.push(this._keyStr.charAt(h)) +return i.join("")},compress:function(a){var b,c,d,e,f,g,h,i,j=[],k=1,l=0,m=!1 +for(a=a.replace(/[^A-Za-z0-9\+\/\=]/g,"");l>4,d=(15&g)<<4|h>>2,e=(3&h)<<6|i,k%2===0?(b=c<<8,m=!0,64!=h&&(j.push(String.fromCharCode(b|d)),m=!1),64!=i&&(b=e<<8,m=!0)):(j.push(String.fromCharCode(b|c)),m=!1,64!=h&&(b=d<<8,m=!0),64!=i&&(j.push(String.fromCharCode(b|e)),m=!1)),k+=3 +return m?(j.push(String.fromCharCode(b)),j=j.join(""),j=String.fromCharCode(256|j.charCodeAt(0))+j.substring(1)):j=j.join(""),j}},O.esri.Tiles.saveAs=function(a){"use strict" var b=a.document,c=function(){return a.URL||a.webkitURL||a},d=a.URL||a.webkitURL||a,e=b.createElementNS("http://www.w3.org/1999/xhtml","a"),f=!a.externalHost&&"download"in e,g=a.webkitRequestFileSystem,h=a.requestFileSystem||g||a.mozRequestFileSystem,i=function(b){(a.setImmediate||a.setTimeout)(function(){throw b},0)},j="application/octet-stream",k=0,l=[],m=function(){for(var a=l.length;a--;){var b=l[a] "string"==typeof b?d.revokeObjectURL(b):b.remove()}l.length=0},n=function(a,b,c){b=[].concat(b) for(var d=b.length;d--;){var e=a["on"+b[d]] @@ -69,10 +131,12 @@ return c.level=b.level,c.resolution=b.resolution,c.scale=b.scale,b.hasOwnPropert var k=new f(parseFloat(d.initialExtent.xmin),parseFloat(d.initialExtent.ymin),parseFloat(d.initialExtent.xmax),parseFloat(d.initialExtent.ymax),i),l=new f(parseFloat(d.fullExtent.xmin),parseFloat(d.fullExtent.ymin),parseFloat(d.fullExtent.xmax),parseFloat(d.fullExtent.ymax),i),m=new g(d.tileInfo),n=new h(m.origin.x,m.origin.y,i) m.origin=n,m.lods=j,b({initExtent:k,fullExtent:l,tileInfo:m,resultObj:d})})}},O.esri.Tiles.TilesStore=function(){this._db=null,this.dbName="offline_tile_store",this.objectStoreName="tilepath",this.isSupported=function(){return!(!window.indexedDB&&!window.openDatabase)},this.store=function(a,b){try{var c=this._db.transaction([this.objectStoreName],"readwrite") c.oncomplete=function(){b(!0)},c.onerror=function(a){b(!1,a.target.error.message)} -var d=c.objectStore(this.objectStoreName),e=d.put(a) +var d=c.objectStore(this.objectStoreName) +a.img=O.esri.Tiles.Base64String.compress(a.img) +var e=d.put(a) e.onsuccess=function(){}}catch(f){b(!1,f.stack)}},this.retrieve=function(a,b){if(null!==this._db){var c=this._db.transaction([this.objectStoreName]).objectStore(this.objectStoreName),d=c.get(a) d.onsuccess=function(a){var c=a.target.result -void 0===c?b(!1,"not found"):b(!0,c)},d.onerror=function(a){b(!1,a)}}},this.deleteAll=function(a){if(null!==this._db){var b=this._db.transaction([this.objectStoreName],"readwrite").objectStore(this.objectStoreName).clear() +void 0===c?b(!1,"not found"):(c.img=O.esri.Tiles.Base64String.decompress(c.img),b(!0,c))},d.onerror=function(a){b(!1,a)}}},this.deleteAll=function(a){if(null!==this._db){var b=this._db.transaction([this.objectStoreName],"readwrite").objectStore(this.objectStoreName).clear() b.onsuccess=function(){a(!0)},b.onerror=function(b){a(!1,b)}}else a(!1,null)},this["delete"]=function(a,b){if(null!==this._db){var c=this._db.transaction([this.objectStoreName],"readwrite").objectStore(this.objectStoreName)["delete"](a) c.onsuccess=function(){b(!0)},c.onerror=function(a){b(!1,a)}}else b(!1,null)},this.getAllTiles=function(a){if(null!==this._db){var b=this._db.transaction([this.objectStoreName]).objectStore(this.objectStoreName).openCursor() b.onsuccess=function(b){var c=b.target.result diff --git a/dist/offline-tiles-advanced-src.js b/dist/offline-tiles-advanced-src.js index fcfa5609..f9bcd488 100644 --- a/dist/offline-tiles-advanced-src.js +++ b/dist/offline-tiles-advanced-src.js @@ -1,4 +1,4 @@ -/*! esri-offline-maps - v3.3.0 - 2016-07-12 +/*! esri-offline-maps - v3.4.0 - 2016-09-13 * Copyright (c) 2016 Environmental Systems Research Institute, Inc. * Apache License*/ define([ @@ -661,6 +661,299 @@ O.esri.Tiles.Base64Utils.wordToBase64=function(/* word[] */wa){ }; /*jslint bitwise: false */ +// Copyright (c) 2013 Pieroxy +// This work is free. You can redistribute it and/or modify it +// under the terms of the WTFPL, Version 2 +// For more information see LICENSE.txt or http://www.wtfpl.net/ +// +// This lib is part of the lz-string project. +// For more information, the home page: +// http://pieroxy.net/blog/pages/lz-string/index.html +// +// Base64 compression / decompression for already compressed content (gif, png, jpg, mp3, ...) +// version 1.4.1 + +/*jslint bitwise: true */ +O.esri.Tiles.Base64String = { + + compressToUTF16 : function (input) { + var output = [], + i,c, + current, + status = 0; + + input = this.compress(input); + + for (i=0 ; i> 1)+32)); + current = (c & 1) << 14; + break; + case 1: + output.push(String.fromCharCode((current + (c >> 2))+32)); + current = (c & 3) << 13; + break; + case 2: + output.push(String.fromCharCode((current + (c >> 3))+32)); + current = (c & 7) << 12; + break; + case 3: + output.push(String.fromCharCode((current + (c >> 4))+32)); + current = (c & 15) << 11; + break; + case 4: + output.push(String.fromCharCode((current + (c >> 5))+32)); + current = (c & 31) << 10; + break; + case 5: + output.push(String.fromCharCode((current + (c >> 6))+32)); + current = (c & 63) << 9; + break; + case 6: + output.push(String.fromCharCode((current + (c >> 7))+32)); + current = (c & 127) << 8; + break; + case 7: + output.push(String.fromCharCode((current + (c >> 8))+32)); + current = (c & 255) << 7; + break; + case 8: + output.push(String.fromCharCode((current + (c >> 9))+32)); + current = (c & 511) << 6; + break; + case 9: + output.push(String.fromCharCode((current + (c >> 10))+32)); + current = (c & 1023) << 5; + break; + case 10: + output.push(String.fromCharCode((current + (c >> 11))+32)); + current = (c & 2047) << 4; + break; + case 11: + output.push(String.fromCharCode((current + (c >> 12))+32)); + current = (c & 4095) << 3; + break; + case 12: + output.push(String.fromCharCode((current + (c >> 13))+32)); + current = (c & 8191) << 2; + break; + case 13: + output.push(String.fromCharCode((current + (c >> 14))+32)); + current = (c & 16383) << 1; + break; + case 14: + output.push(String.fromCharCode((current + (c >> 15))+32, (c & 32767)+32)); + status = 0; + break; + } + } + output.push(String.fromCharCode(current + 32)); + return output.join(''); + }, + + + decompressFromUTF16 : function (input) { + var output = [], + current,c, + status=0, + i = 0; + + while (i < input.length) { + c = input.charCodeAt(i) - 32; + + switch (status++) { + case 0: + current = c << 1; + break; + case 1: + output.push(String.fromCharCode(current | (c >> 14))); + current = (c&16383) << 2; + break; + case 2: + output.push(String.fromCharCode(current | (c >> 13))); + current = (c&8191) << 3; + break; + case 3: + output.push(String.fromCharCode(current | (c >> 12))); + current = (c&4095) << 4; + break; + case 4: + output.push(String.fromCharCode(current | (c >> 11))); + current = (c&2047) << 5; + break; + case 5: + output.push(String.fromCharCode(current | (c >> 10))); + current = (c&1023) << 6; + break; + case 6: + output.push(String.fromCharCode(current | (c >> 9))); + current = (c&511) << 7; + break; + case 7: + output.push(String.fromCharCode(current | (c >> 8))); + current = (c&255) << 8; + break; + case 8: + output.push(String.fromCharCode(current | (c >> 7))); + current = (c&127) << 9; + break; + case 9: + output.push(String.fromCharCode(current | (c >> 6))); + current = (c&63) << 10; + break; + case 10: + output.push(String.fromCharCode(current | (c >> 5))); + current = (c&31) << 11; + break; + case 11: + output.push(String.fromCharCode(current | (c >> 4))); + current = (c&15) << 12; + break; + case 12: + output.push(String.fromCharCode(current | (c >> 3))); + current = (c&7) << 13; + break; + case 13: + output.push(String.fromCharCode(current | (c >> 2))); + current = (c&3) << 14; + break; + case 14: + output.push(String.fromCharCode(current | (c >> 1))); + current = (c&1) << 15; + break; + case 15: + output.push(String.fromCharCode(current | c)); + status=0; + break; + } + + + i++; + } + + return this.decompress(output.join('')); + //return output; + + }, + + + // private property + _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", // jshint ignore:line + + decompress : function (input) { + var output = []; + var chr1, chr2, chr3, enc1, enc2, enc3, enc4; + var i = 1; + var odd = input.charCodeAt(0) >> 8; + + while (i < input.length*2 && (i < input.length*2-1 || odd===0)) { + + if (i%2===0) { + chr1 = input.charCodeAt(i/2) >> 8; + chr2 = input.charCodeAt(i/2) & 255; + if (i/2+1 < input.length) { + chr3 = input.charCodeAt(i / 2 + 1) >> 8; + } + else { + chr3 = NaN; + } + } else { + chr1 = input.charCodeAt((i-1)/2) & 255; + if ((i+1)/2 < input.length) { + chr2 = input.charCodeAt((i+1)/2) >> 8; + chr3 = input.charCodeAt((i+1)/2) & 255; + } else { + chr2 = chr3 = NaN; + } + } + i+=3; + + enc1 = chr1 >> 2; + enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); + enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); + enc4 = chr3 & 63; + + if (isNaN(chr2) || (i==input.length*2+1 && odd)) { + enc3 = enc4 = 64; + } else if (isNaN(chr3) || (i==input.length*2 && odd)) { + enc4 = 64; + } + + output.push(this._keyStr.charAt(enc1)); + output.push(this._keyStr.charAt(enc2)); + output.push(this._keyStr.charAt(enc3)); + output.push(this._keyStr.charAt(enc4)); + } + + return output.join(''); + }, + + compress : function (input) { + var output = [], + ol = 1, + output_, + chr1, chr2, chr3, + enc1, enc2, enc3, enc4, + i = 0, flush=false; + + input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); // jshint ignore:line + + while (i < input.length) { + + enc1 = this._keyStr.indexOf(input.charAt(i++)); + enc2 = this._keyStr.indexOf(input.charAt(i++)); + enc3 = this._keyStr.indexOf(input.charAt(i++)); + enc4 = this._keyStr.indexOf(input.charAt(i++)); + + chr1 = (enc1 << 2) | (enc2 >> 4); + chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); + chr3 = ((enc3 & 3) << 6) | enc4; + + if (ol%2===0) { + output_ = chr1 << 8; + flush = true; + + if (enc3 != 64) { + output.push(String.fromCharCode(output_ | chr2)); + flush = false; + } + if (enc4 != 64) { + output_ = chr3 << 8; + flush = true; + } + } else { + output.push(String.fromCharCode(output_ | chr1)); + flush = false; + + if (enc3 != 64) { + output_ = chr2 << 8; + flush = true; + } + if (enc4 != 64) { + output.push(String.fromCharCode(output_ | chr3)); + flush = false; + } + } + ol+=3; + } + + if (flush) { + output.push(String.fromCharCode(output_)); + output = output.join(''); + output = String.fromCharCode(output.charCodeAt(0)|256) + output.substring(1); + } else { + output = output.join(''); + } + + return output; + + } +}; + +/*jslint bitwise: false */ + /* FileSaver.js * A saveAs() FileSaver implementation. * 2013-10-21 @@ -918,7 +1211,7 @@ O.esri.Tiles.TilesCore = function(){ */ this._getTiles = function(image,imageType,url,tileid,store,query,showBlankTiles){ store.retrieve(url, function(success, offlineTile) - { console.log("TILE RETURN " + success + ", " + offlineTile.url); + { console.log("TILE RETURN " + success + ", " + offlineTile.url + ", " + tileid); /* when the .getTileUrl() callback is triggered we replace the temporary URL originally returned by the data:image url */ // search for the img with src="void:"+level+"-"+row+"-"+col and replace with actual url image = query("img[src="+tileid+"]")[0]; @@ -1348,6 +1641,7 @@ O.esri.Tiles.TilesStore = function(){ }; var objectStore = transaction.objectStore(this.objectStoreName); + urlDataPair.img = O.esri.Tiles.Base64String.compress(urlDataPair.img); var request = objectStore.put(urlDataPair); request.onsuccess = function() { @@ -1381,6 +1675,7 @@ O.esri.Tiles.TilesStore = function(){ } else { + result.img = O.esri.Tiles.Base64String.decompress(result.img); callback(true,result); } }; diff --git a/dist/offline-tiles-basic-min.js b/dist/offline-tiles-basic-min.js index f83c8aa7..8201b180 100644 --- a/dist/offline-tiles-basic-min.js +++ b/dist/offline-tiles-basic-min.js @@ -19,7 +19,69 @@ return d<<16|65535&c},O.esri.Tiles.Base64Utils.stringToWord=function(a){for(var return d},O.esri.Tiles.Base64Utils.wordToString=function(a){for(var b=8,c=(1<e;e+=b)d.push(String.fromCharCode(a[e>>5]>>>e%32&c)) return d.join("")},O.esri.Tiles.Base64Utils.wordToHex=function(a){for(var b="0123456789abcdef",c=[],d=0,e=4*a.length;e>d;d++)c.push(b.charAt(a[d>>2]>>d%4*8+4&15)+b.charAt(a[d>>2]>>d%4*8&15)) return c.join("")},O.esri.Tiles.Base64Utils.wordToBase64=function(a){for(var b="=",c="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",d=[],e=0,f=4*a.length;f>e;e+=3)for(var g=(a[e>>2]>>8*(e%4)&255)<<16|(a[e+1>>2]>>8*((e+1)%4)&255)<<8|a[e+2>>2]>>8*((e+2)%4)&255,h=0;4>h;h++)8*e+6*h>32*a.length?d.push(b):d.push(c.charAt(g>>6*(3-h)&63)) -return d.join("")},O.esri.Tiles.saveAs=function(a){"use strict" +return d.join("")},O.esri.Tiles.Base64String={compressToUTF16:function(a){var b,c,d,e=[],f=0 +for(a=this.compress(a),b=0;b>1)+32)),d=(1&c)<<14 +break +case 1:e.push(String.fromCharCode(d+(c>>2)+32)),d=(3&c)<<13 +break +case 2:e.push(String.fromCharCode(d+(c>>3)+32)),d=(7&c)<<12 +break +case 3:e.push(String.fromCharCode(d+(c>>4)+32)),d=(15&c)<<11 +break +case 4:e.push(String.fromCharCode(d+(c>>5)+32)),d=(31&c)<<10 +break +case 5:e.push(String.fromCharCode(d+(c>>6)+32)),d=(63&c)<<9 +break +case 6:e.push(String.fromCharCode(d+(c>>7)+32)),d=(127&c)<<8 +break +case 7:e.push(String.fromCharCode(d+(c>>8)+32)),d=(255&c)<<7 +break +case 8:e.push(String.fromCharCode(d+(c>>9)+32)),d=(511&c)<<6 +break +case 9:e.push(String.fromCharCode(d+(c>>10)+32)),d=(1023&c)<<5 +break +case 10:e.push(String.fromCharCode(d+(c>>11)+32)),d=(2047&c)<<4 +break +case 11:e.push(String.fromCharCode(d+(c>>12)+32)),d=(4095&c)<<3 +break +case 12:e.push(String.fromCharCode(d+(c>>13)+32)),d=(8191&c)<<2 +break +case 13:e.push(String.fromCharCode(d+(c>>14)+32)),d=(16383&c)<<1 +break +case 14:e.push(String.fromCharCode(d+(c>>15)+32,(32767&c)+32)),f=0}return e.push(String.fromCharCode(d+32)),e.join("")},decompressFromUTF16:function(a){for(var b,c,d=[],e=0,f=0;f>14)),b=(16383&c)<<2 +break +case 2:d.push(String.fromCharCode(b|c>>13)),b=(8191&c)<<3 +break +case 3:d.push(String.fromCharCode(b|c>>12)),b=(4095&c)<<4 +break +case 4:d.push(String.fromCharCode(b|c>>11)),b=(2047&c)<<5 +break +case 5:d.push(String.fromCharCode(b|c>>10)),b=(1023&c)<<6 +break +case 6:d.push(String.fromCharCode(b|c>>9)),b=(511&c)<<7 +break +case 7:d.push(String.fromCharCode(b|c>>8)),b=(255&c)<<8 +break +case 8:d.push(String.fromCharCode(b|c>>7)),b=(127&c)<<9 +break +case 9:d.push(String.fromCharCode(b|c>>6)),b=(63&c)<<10 +break +case 10:d.push(String.fromCharCode(b|c>>5)),b=(31&c)<<11 +break +case 11:d.push(String.fromCharCode(b|c>>4)),b=(15&c)<<12 +break +case 12:d.push(String.fromCharCode(b|c>>3)),b=(7&c)<<13 +break +case 13:d.push(String.fromCharCode(b|c>>2)),b=(3&c)<<14 +break +case 14:d.push(String.fromCharCode(b|c>>1)),b=(1&c)<<15 +break +case 15:d.push(String.fromCharCode(b|c)),e=0}f++}return this.decompress(d.join(""))},_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",decompress:function(a){for(var b,c,d,e,f,g,h,i=[],j=1,k=a.charCodeAt(0)>>8;j<2*a.length&&(j<2*a.length-1||0===k);)j%2===0?(b=a.charCodeAt(j/2)>>8,c=255&a.charCodeAt(j/2),d=j/2+1>8:NaN):(b=255&a.charCodeAt((j-1)/2),(j+1)/2>8,d=255&a.charCodeAt((j+1)/2)):c=d=NaN),j+=3,e=b>>2,f=(3&b)<<4|c>>4,g=(15&c)<<2|d>>6,h=63&d,isNaN(c)||j==2*a.length+1&&k?g=h=64:(isNaN(d)||j==2*a.length&&k)&&(h=64),i.push(this._keyStr.charAt(e)),i.push(this._keyStr.charAt(f)),i.push(this._keyStr.charAt(g)),i.push(this._keyStr.charAt(h)) +return i.join("")},compress:function(a){var b,c,d,e,f,g,h,i,j=[],k=1,l=0,m=!1 +for(a=a.replace(/[^A-Za-z0-9\+\/\=]/g,"");l>4,d=(15&g)<<4|h>>2,e=(3&h)<<6|i,k%2===0?(b=c<<8,m=!0,64!=h&&(j.push(String.fromCharCode(b|d)),m=!1),64!=i&&(b=e<<8,m=!0)):(j.push(String.fromCharCode(b|c)),m=!1,64!=h&&(b=d<<8,m=!0),64!=i&&(j.push(String.fromCharCode(b|e)),m=!1)),k+=3 +return m?(j.push(String.fromCharCode(b)),j=j.join(""),j=String.fromCharCode(256|j.charCodeAt(0))+j.substring(1)):j=j.join(""),j}},O.esri.Tiles.saveAs=function(a){"use strict" var b=a.document,c=function(){return a.URL||a.webkitURL||a},d=a.URL||a.webkitURL||a,e=b.createElementNS("http://www.w3.org/1999/xhtml","a"),f=!a.externalHost&&"download"in e,g=a.webkitRequestFileSystem,h=a.requestFileSystem||g||a.mozRequestFileSystem,i=function(b){(a.setImmediate||a.setTimeout)(function(){throw b},0)},j="application/octet-stream",k=0,l=[],m=function(){for(var a=l.length;a--;){var b=l[a] "string"==typeof b?d.revokeObjectURL(b):b.remove()}l.length=0},n=function(a,b,c){b=[].concat(b) for(var d=b.length;d--;){var e=a["on"+b[d]] @@ -58,10 +120,12 @@ return c.level=b.level,c.resolution=b.resolution,c.scale=b.scale,b.hasOwnPropert var k=new f(parseFloat(d.initialExtent.xmin),parseFloat(d.initialExtent.ymin),parseFloat(d.initialExtent.xmax),parseFloat(d.initialExtent.ymax),i),l=new f(parseFloat(d.fullExtent.xmin),parseFloat(d.fullExtent.ymin),parseFloat(d.fullExtent.xmax),parseFloat(d.fullExtent.ymax),i),m=new g(d.tileInfo),n=new h(m.origin.x,m.origin.y,i) m.origin=n,m.lods=j,b({initExtent:k,fullExtent:l,tileInfo:m,resultObj:d})})}},O.esri.Tiles.TilesStore=function(){this._db=null,this.dbName="offline_tile_store",this.objectStoreName="tilepath",this.isSupported=function(){return!(!window.indexedDB&&!window.openDatabase)},this.store=function(a,b){try{var c=this._db.transaction([this.objectStoreName],"readwrite") c.oncomplete=function(){b(!0)},c.onerror=function(a){b(!1,a.target.error.message)} -var d=c.objectStore(this.objectStoreName),e=d.put(a) +var d=c.objectStore(this.objectStoreName) +a.img=O.esri.Tiles.Base64String.compress(a.img) +var e=d.put(a) e.onsuccess=function(){}}catch(f){b(!1,f.stack)}},this.retrieve=function(a,b){if(null!==this._db){var c=this._db.transaction([this.objectStoreName]).objectStore(this.objectStoreName),d=c.get(a) d.onsuccess=function(a){var c=a.target.result -void 0===c?b(!1,"not found"):b(!0,c)},d.onerror=function(a){b(!1,a)}}},this.deleteAll=function(a){if(null!==this._db){var b=this._db.transaction([this.objectStoreName],"readwrite").objectStore(this.objectStoreName).clear() +void 0===c?b(!1,"not found"):(c.img=O.esri.Tiles.Base64String.decompress(c.img),b(!0,c))},d.onerror=function(a){b(!1,a)}}},this.deleteAll=function(a){if(null!==this._db){var b=this._db.transaction([this.objectStoreName],"readwrite").objectStore(this.objectStoreName).clear() b.onsuccess=function(){a(!0)},b.onerror=function(b){a(!1,b)}}else a(!1,null)},this["delete"]=function(a,b){if(null!==this._db){var c=this._db.transaction([this.objectStoreName],"readwrite").objectStore(this.objectStoreName)["delete"](a) c.onsuccess=function(){b(!0)},c.onerror=function(a){b(!1,a)}}else b(!1,null)},this.getAllTiles=function(a){if(null!==this._db){var b=this._db.transaction([this.objectStoreName]).objectStore(this.objectStoreName).openCursor() b.onsuccess=function(b){var c=b.target.result diff --git a/dist/offline-tiles-basic-src.js b/dist/offline-tiles-basic-src.js index 769fba4e..5ba52b58 100644 --- a/dist/offline-tiles-basic-src.js +++ b/dist/offline-tiles-basic-src.js @@ -1,4 +1,4 @@ -/*! esri-offline-maps - v3.3.0 - 2016-07-12 +/*! esri-offline-maps - v3.4.0 - 2016-09-13 * Copyright (c) 2016 Environmental Systems Research Institute, Inc. * Apache License*/ define([ @@ -492,6 +492,299 @@ O.esri.Tiles.Base64Utils.wordToBase64=function(/* word[] */wa){ }; /*jslint bitwise: false */ +// Copyright (c) 2013 Pieroxy +// This work is free. You can redistribute it and/or modify it +// under the terms of the WTFPL, Version 2 +// For more information see LICENSE.txt or http://www.wtfpl.net/ +// +// This lib is part of the lz-string project. +// For more information, the home page: +// http://pieroxy.net/blog/pages/lz-string/index.html +// +// Base64 compression / decompression for already compressed content (gif, png, jpg, mp3, ...) +// version 1.4.1 + +/*jslint bitwise: true */ +O.esri.Tiles.Base64String = { + + compressToUTF16 : function (input) { + var output = [], + i,c, + current, + status = 0; + + input = this.compress(input); + + for (i=0 ; i> 1)+32)); + current = (c & 1) << 14; + break; + case 1: + output.push(String.fromCharCode((current + (c >> 2))+32)); + current = (c & 3) << 13; + break; + case 2: + output.push(String.fromCharCode((current + (c >> 3))+32)); + current = (c & 7) << 12; + break; + case 3: + output.push(String.fromCharCode((current + (c >> 4))+32)); + current = (c & 15) << 11; + break; + case 4: + output.push(String.fromCharCode((current + (c >> 5))+32)); + current = (c & 31) << 10; + break; + case 5: + output.push(String.fromCharCode((current + (c >> 6))+32)); + current = (c & 63) << 9; + break; + case 6: + output.push(String.fromCharCode((current + (c >> 7))+32)); + current = (c & 127) << 8; + break; + case 7: + output.push(String.fromCharCode((current + (c >> 8))+32)); + current = (c & 255) << 7; + break; + case 8: + output.push(String.fromCharCode((current + (c >> 9))+32)); + current = (c & 511) << 6; + break; + case 9: + output.push(String.fromCharCode((current + (c >> 10))+32)); + current = (c & 1023) << 5; + break; + case 10: + output.push(String.fromCharCode((current + (c >> 11))+32)); + current = (c & 2047) << 4; + break; + case 11: + output.push(String.fromCharCode((current + (c >> 12))+32)); + current = (c & 4095) << 3; + break; + case 12: + output.push(String.fromCharCode((current + (c >> 13))+32)); + current = (c & 8191) << 2; + break; + case 13: + output.push(String.fromCharCode((current + (c >> 14))+32)); + current = (c & 16383) << 1; + break; + case 14: + output.push(String.fromCharCode((current + (c >> 15))+32, (c & 32767)+32)); + status = 0; + break; + } + } + output.push(String.fromCharCode(current + 32)); + return output.join(''); + }, + + + decompressFromUTF16 : function (input) { + var output = [], + current,c, + status=0, + i = 0; + + while (i < input.length) { + c = input.charCodeAt(i) - 32; + + switch (status++) { + case 0: + current = c << 1; + break; + case 1: + output.push(String.fromCharCode(current | (c >> 14))); + current = (c&16383) << 2; + break; + case 2: + output.push(String.fromCharCode(current | (c >> 13))); + current = (c&8191) << 3; + break; + case 3: + output.push(String.fromCharCode(current | (c >> 12))); + current = (c&4095) << 4; + break; + case 4: + output.push(String.fromCharCode(current | (c >> 11))); + current = (c&2047) << 5; + break; + case 5: + output.push(String.fromCharCode(current | (c >> 10))); + current = (c&1023) << 6; + break; + case 6: + output.push(String.fromCharCode(current | (c >> 9))); + current = (c&511) << 7; + break; + case 7: + output.push(String.fromCharCode(current | (c >> 8))); + current = (c&255) << 8; + break; + case 8: + output.push(String.fromCharCode(current | (c >> 7))); + current = (c&127) << 9; + break; + case 9: + output.push(String.fromCharCode(current | (c >> 6))); + current = (c&63) << 10; + break; + case 10: + output.push(String.fromCharCode(current | (c >> 5))); + current = (c&31) << 11; + break; + case 11: + output.push(String.fromCharCode(current | (c >> 4))); + current = (c&15) << 12; + break; + case 12: + output.push(String.fromCharCode(current | (c >> 3))); + current = (c&7) << 13; + break; + case 13: + output.push(String.fromCharCode(current | (c >> 2))); + current = (c&3) << 14; + break; + case 14: + output.push(String.fromCharCode(current | (c >> 1))); + current = (c&1) << 15; + break; + case 15: + output.push(String.fromCharCode(current | c)); + status=0; + break; + } + + + i++; + } + + return this.decompress(output.join('')); + //return output; + + }, + + + // private property + _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", // jshint ignore:line + + decompress : function (input) { + var output = []; + var chr1, chr2, chr3, enc1, enc2, enc3, enc4; + var i = 1; + var odd = input.charCodeAt(0) >> 8; + + while (i < input.length*2 && (i < input.length*2-1 || odd===0)) { + + if (i%2===0) { + chr1 = input.charCodeAt(i/2) >> 8; + chr2 = input.charCodeAt(i/2) & 255; + if (i/2+1 < input.length) { + chr3 = input.charCodeAt(i / 2 + 1) >> 8; + } + else { + chr3 = NaN; + } + } else { + chr1 = input.charCodeAt((i-1)/2) & 255; + if ((i+1)/2 < input.length) { + chr2 = input.charCodeAt((i+1)/2) >> 8; + chr3 = input.charCodeAt((i+1)/2) & 255; + } else { + chr2 = chr3 = NaN; + } + } + i+=3; + + enc1 = chr1 >> 2; + enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); + enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); + enc4 = chr3 & 63; + + if (isNaN(chr2) || (i==input.length*2+1 && odd)) { + enc3 = enc4 = 64; + } else if (isNaN(chr3) || (i==input.length*2 && odd)) { + enc4 = 64; + } + + output.push(this._keyStr.charAt(enc1)); + output.push(this._keyStr.charAt(enc2)); + output.push(this._keyStr.charAt(enc3)); + output.push(this._keyStr.charAt(enc4)); + } + + return output.join(''); + }, + + compress : function (input) { + var output = [], + ol = 1, + output_, + chr1, chr2, chr3, + enc1, enc2, enc3, enc4, + i = 0, flush=false; + + input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); // jshint ignore:line + + while (i < input.length) { + + enc1 = this._keyStr.indexOf(input.charAt(i++)); + enc2 = this._keyStr.indexOf(input.charAt(i++)); + enc3 = this._keyStr.indexOf(input.charAt(i++)); + enc4 = this._keyStr.indexOf(input.charAt(i++)); + + chr1 = (enc1 << 2) | (enc2 >> 4); + chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); + chr3 = ((enc3 & 3) << 6) | enc4; + + if (ol%2===0) { + output_ = chr1 << 8; + flush = true; + + if (enc3 != 64) { + output.push(String.fromCharCode(output_ | chr2)); + flush = false; + } + if (enc4 != 64) { + output_ = chr3 << 8; + flush = true; + } + } else { + output.push(String.fromCharCode(output_ | chr1)); + flush = false; + + if (enc3 != 64) { + output_ = chr2 << 8; + flush = true; + } + if (enc4 != 64) { + output.push(String.fromCharCode(output_ | chr3)); + flush = false; + } + } + ol+=3; + } + + if (flush) { + output.push(String.fromCharCode(output_)); + output = output.join(''); + output = String.fromCharCode(output.charCodeAt(0)|256) + output.substring(1); + } else { + output = output.join(''); + } + + return output; + + } +}; + +/*jslint bitwise: false */ + /* FileSaver.js * A saveAs() FileSaver implementation. * 2013-10-21 @@ -749,7 +1042,7 @@ O.esri.Tiles.TilesCore = function(){ */ this._getTiles = function(image,imageType,url,tileid,store,query,showBlankTiles){ store.retrieve(url, function(success, offlineTile) - { console.log("TILE RETURN " + success + ", " + offlineTile.url); + { console.log("TILE RETURN " + success + ", " + offlineTile.url + ", " + tileid); /* when the .getTileUrl() callback is triggered we replace the temporary URL originally returned by the data:image url */ // search for the img with src="void:"+level+"-"+row+"-"+col and replace with actual url image = query("img[src="+tileid+"]")[0]; @@ -1179,6 +1472,7 @@ O.esri.Tiles.TilesStore = function(){ }; var objectStore = transaction.objectStore(this.objectStoreName); + urlDataPair.img = O.esri.Tiles.Base64String.compress(urlDataPair.img); var request = objectStore.put(urlDataPair); request.onsuccess = function() { @@ -1212,6 +1506,7 @@ O.esri.Tiles.TilesStore = function(){ } else { + result.img = O.esri.Tiles.Base64String.decompress(result.img); callback(true,result); } }; diff --git a/dist/offline-tpk-min.js b/dist/offline-tpk-min.js index ae7c08a5..4b6e7381 100644 --- a/dist/offline-tpk-min.js +++ b/dist/offline-tpk-min.js @@ -51,10 +51,12 @@ return 1===b.length?"000"+b:2===b.length?"00"+b:3===b.length?"0"+b:b.substr(0,b. return 16+5*f},_getCacheFilePath:function(a,b,c,d){var e=[] return e.push(a),e.push("/"),e.push("L"),e.push(10>b?"0"+b:b),e.push("/"),e.push("R"),e.push(this._int2HexString(c)),e.push("C"),e.push(this._int2HexString(d)),e.join("")},_bytes2MBs:function(a){return(a>>>20)+"."+(2046&a)}})}),"undefined"!=typeof O?O.esri.TPK={}:(O={},O.esri={TPK:{},Tiles:{}}),O.esri.Tiles.TilesStore=function(){this._db=null,this.dbName="offline_tile_store",this.objectStoreName="tilepath",this.isSupported=function(){return!(!window.indexedDB&&!window.openDatabase)},this.store=function(a,b){try{var c=this._db.transaction([this.objectStoreName],"readwrite") c.oncomplete=function(){b(!0)},c.onerror=function(a){b(!1,a.target.error.message)} -var d=c.objectStore(this.objectStoreName),e=d.put(a) +var d=c.objectStore(this.objectStoreName) +a.img=O.esri.Tiles.Base64String.compress(a.img) +var e=d.put(a) e.onsuccess=function(){}}catch(f){b(!1,f.stack)}},this.retrieve=function(a,b){if(null!==this._db){var c=this._db.transaction([this.objectStoreName]).objectStore(this.objectStoreName),d=c.get(a) d.onsuccess=function(a){var c=a.target.result -void 0===c?b(!1,"not found"):b(!0,c)},d.onerror=function(a){b(!1,a)}}},this.deleteAll=function(a){if(null!==this._db){var b=this._db.transaction([this.objectStoreName],"readwrite").objectStore(this.objectStoreName).clear() +void 0===c?b(!1,"not found"):(c.img=O.esri.Tiles.Base64String.decompress(c.img),b(!0,c))},d.onerror=function(a){b(!1,a)}}},this.deleteAll=function(a){if(null!==this._db){var b=this._db.transaction([this.objectStoreName],"readwrite").objectStore(this.objectStoreName).clear() b.onsuccess=function(){a(!0)},b.onerror=function(b){a(!1,b)}}else a(!1,null)},this["delete"]=function(a,b){if(null!==this._db){var c=this._db.transaction([this.objectStoreName],"readwrite").objectStore(this.objectStoreName)["delete"](a) c.onsuccess=function(){b(!0)},c.onerror=function(a){b(!1,a)}}else b(!1,null)},this.getAllTiles=function(a){if(null!==this._db){var b=this._db.transaction([this.objectStoreName]).objectStore(this.objectStoreName).openCursor() b.onsuccess=function(b){var c=b.target.result diff --git a/dist/offline-tpk-src.js b/dist/offline-tpk-src.js index 6fd468f7..40a00a83 100644 --- a/dist/offline-tpk-src.js +++ b/dist/offline-tpk-src.js @@ -1,4 +1,4 @@ -/*! esri-offline-maps - v3.3.0 - 2016-07-12 +/*! esri-offline-maps - v3.4.0 - 2016-09-13 * Copyright (c) 2016 Environmental Systems Research Institute, Inc. * Apache License*/ /** @@ -794,6 +794,7 @@ O.esri.Tiles.TilesStore = function(){ }; var objectStore = transaction.objectStore(this.objectStoreName); + urlDataPair.img = O.esri.Tiles.Base64String.compress(urlDataPair.img); var request = objectStore.put(urlDataPair); request.onsuccess = function() { @@ -827,6 +828,7 @@ O.esri.Tiles.TilesStore = function(){ } else { + result.img = O.esri.Tiles.Base64String.decompress(result.img); callback(true,result); } }; diff --git a/lib/tiles/TilesStore.js b/lib/tiles/TilesStore.js index 08dd376a..861f1778 100644 --- a/lib/tiles/TilesStore.js +++ b/lib/tiles/TilesStore.js @@ -53,6 +53,7 @@ O.esri.Tiles.TilesStore = function(){ }; var objectStore = transaction.objectStore(this.objectStoreName); + urlDataPair.img = O.esri.Tiles.Base64String.compress(urlDataPair.img); var request = objectStore.put(urlDataPair); request.onsuccess = function() { @@ -86,6 +87,7 @@ O.esri.Tiles.TilesStore = function(){ } else { + result.img = O.esri.Tiles.Base64String.decompress(result.img); callback(true,result); } }; diff --git a/package.json b/package.json index 0e59a8b8..315948da 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "esri-offline-maps", - "version": "3.3.2", + "version": "3.4.0", "description": "Lightweight set of libraries for working offline with map tiles and editing with ArcGIS feature services", "author": "Andy Gup (http://blog.andygup.net)", "license": "Apache 2.0", diff --git a/samples/package.json b/samples/package.json index c9ffcdcc..02ba7340 100644 --- a/samples/package.json +++ b/samples/package.json @@ -9,7 +9,7 @@ "appHomePage": "appcache-tiles.html", "optimizedApiURL": "../samples/jsolib", "arcGISBaseURL": "http://js.arcgis.com/3.14", - "version": "3.3.2", + "version": "3.4.0", "private": true, "description": "manifest generator project", "repository": {