first commit
This commit is contained in:
7
lib/leaflet_plugins/leaflet-PouchDBCached-1.0.0/CHANGELOG
Executable file
7
lib/leaflet_plugins/leaflet-PouchDBCached-1.0.0/CHANGELOG
Executable file
@@ -0,0 +1,7 @@
|
||||
|
||||
# 1.0.0 (2019-02-06)
|
||||
|
||||
* Switched from base64-encoded images to PouchDB attachments (should perform
|
||||
much better)
|
||||
|
||||
|
1
lib/leaflet_plugins/leaflet-PouchDBCached-1.0.0/L.TileLayer.PouchDBCached.min.js
vendored
Executable file
1
lib/leaflet_plugins/leaflet-PouchDBCached-1.0.0/L.TileLayer.PouchDBCached.min.js
vendored
Executable file
@@ -0,0 +1 @@
|
||||
if(!HTMLCanvasElement.prototype.toBlob){Object.defineProperty(HTMLCanvasElement.prototype,"toBlob",{value:function(callback,type,quality){var dataURL=this.toDataURL(type,quality).split(",")[1];setTimeout(function(){var binStr=atob(dataURL),len=binStr.length,arr=new Uint8Array(len);for(var i=0;i<len;i+=1){arr[i]=binStr.charCodeAt(i)}callback(new Blob([arr],{type:type||"image/png"}))})}})}L.TileLayer.addInitHook(function(){if(!this.options.useCache){this._db=null;return}this._db=new PouchDB("offline-tiles")});L.TileLayer.prototype.options.useCache=false;L.TileLayer.prototype.options.saveToCache=true;L.TileLayer.prototype.options.useOnlyCache=false;L.TileLayer.prototype.options.cacheFormat="image/png";L.TileLayer.prototype.options.cacheMaxAge=24*3600*1000;L.TileLayer.include({createTile:function(coords,done){var tile=document.createElement("img");tile.onerror=L.bind(this._tileOnError,this,done,tile);if(this.options.crossOrigin){tile.crossOrigin=""}tile.alt="";var tileUrl=this.getTileUrl(coords);if(this.options.useCache){this._db.get(tileUrl,{revs_info:true},this._onCacheLookup(tile,tileUrl,done))}else{tile.onload=L.bind(this._tileOnLoad,this,done,tile);tile.src=tileUrl}return tile},_onCacheLookup:function(tile,tileUrl,done){return function(err,data){if(data){return this._onCacheHit(tile,tileUrl,data,done)}else{return this._onCacheMiss(tile,tileUrl,done)}}.bind(this)},_onCacheHit:function(tile,tileUrl,data,done){this.fire("tilecachehit",{tile:tile,url:tileUrl});this._db.getAttachment(tileUrl,"tile").then(function(blob){var url=URL.createObjectURL(blob);if(Date.now()>data.timestamp+this.options.cacheMaxAge&&!this.options.useOnlyCache){console.log("Tile is too old: ",tileUrl);if(this.options.saveToCache){tile.onload=L.bind(this._saveTile,this,tile,tileUrl,data._revs_info[0].rev,done)}tile.crossOrigin="Anonymous";tile.src=tileUrl;tile.onerror=function(ev){this.src=url}}else{tile.onload=L.bind(this._tileOnLoad,this,done,tile);tile.src=url}}.bind(this))},_onCacheMiss:function(tile,tileUrl,done){this.fire("tilecachemiss",{tile:tile,url:tileUrl});if(this.options.useOnlyCache){tile.onload=L.Util.falseFn;tile.src=L.Util.emptyImageUrl}else{if(this.options.saveToCache){tile.onload=L.bind(this._saveTile,this,tile,tileUrl,undefined,done)}else{tile.onload=L.bind(this._tileOnLoad,this,done,tile)}tile.crossOrigin="Anonymous";tile.src=tileUrl}},_saveTile:function(tile,tileUrl,existingRevision,done){if(!this.options.saveToCache){return}var canvas=document.createElement("canvas");canvas.width=tile.naturalWidth||tile.width;canvas.height=tile.naturalHeight||tile.height;var context=canvas.getContext("2d");context.drawImage(tile,0,0);var format=this.options.cacheFormat;canvas.toBlob(function(blob){this._db.put({_id:tileUrl,_rev:existingRevision,timestamp:Date.now()}).then(function(status){return this._db.putAttachment(tileUrl,"tile",status.rev,blob,format)}.bind(this)).then(function(resp){if(done){done()}}).catch(function(){if(done){done()}})}.bind(this),format)},seed:function(bbox,minZoom,maxZoom){if(!this.options.useCache){return}if(minZoom>maxZoom){return}if(!this._map){return}var queue=[];for(var z=minZoom;z<=maxZoom;z+=1){var northEastPoint=this._map.project(bbox.getNorthEast(),z);var southWestPoint=this._map.project(bbox.getSouthWest(),z);var tileBounds=this._pxBoundsToTileRange(L.bounds([northEastPoint,southWestPoint]));for(var j=tileBounds.min.y;j<=tileBounds.max.y;j+=1){for(var i=tileBounds.min.x;i<=tileBounds.max.x;i+=1){var point=new L.Point(i,j);point.z=z;queue.push(this._getTileUrl(point))}}}var seedData={bbox:bbox,minZoom:minZoom,maxZoom:maxZoom,queueLength:queue.length};this.fire("seedstart",seedData);var tile=this._createTile();tile._layer=this;this._seedOneTile(tile,queue,seedData);return this},_createTile:function(){return document.createElement("img")},_getTileUrl:function(coords){var zoom=coords.z;if(this.options.zoomReverse){zoom=this.options.maxZoom-zoom}zoom+=this.options.zoomOffset;return L.Util.template(this._url,L.extend({r:this.options.detectRetina&&L.Browser.retina&&this.options.maxZoom>0?"@2x":"",s:this._getSubdomain(coords),x:coords.x,y:this.options.tms?this._globalTileRange.max.y-coords.y:coords.y,z:this.options.maxNativeZoom?Math.min(zoom,this.options.maxNativeZoom):zoom},this.options))},_seedOneTile:function(tile,remaining,seedData){if(!remaining.length){this.fire("seedend",seedData);return}this.fire("seedprogress",{bbox:seedData.bbox,minZoom:seedData.minZoom,maxZoom:seedData.maxZoom,queueLength:seedData.queueLength,remainingLength:remaining.length});var url=remaining.shift();this._db.get(url,function(err,data){if(!data){tile.onload=function(ev){this._saveTile(tile,url,null);this._seedOneTile(tile,remaining,seedData)}.bind(this);tile.crossOrigin="Anonymous";tile.src=url}else{this._seedOneTile(tile,remaining,seedData)}}.bind(this))}});
|
82
lib/leaflet_plugins/leaflet-PouchDBCached-1.0.0/readme.md
Executable file
82
lib/leaflet_plugins/leaflet-PouchDBCached-1.0.0/readme.md
Executable file
@@ -0,0 +1,82 @@
|
||||
|
||||
|
||||
Allows all Leaflet TileLayers to cache into PouchDB for offline use, in a transparent fashion.
|
||||
|
||||
There is a [demo](http://mazemap.github.io/Leaflet.TileLayer.PouchDBCached/demo.html) available, which shows cache hits/misses/seeds in the browser's developer console.
|
||||
|
||||
# Dependencies
|
||||
|
||||
Tested with Leaflet 1.4.0 and PouchDB 7.0.0.
|
||||
|
||||
You probably want to load Leaflet, PouchDB and Leaflet.TileLayer.PouchDB like so:
|
||||
|
||||
```html
|
||||
<script src="https://unpkg.com/leaflet@^1.0.0/dist/leaflet-src.js"></script>
|
||||
<script src="https://unpkg.com/pouchdb@^5.2.0/dist/pouchdb.js"></script>
|
||||
<script src="https://unpkg.com/leaflet.tilelayer.pouchdbcached@latest/L.TileLayer.PouchDBCached.js"></script>
|
||||
```
|
||||
|
||||
If you are still using Leaflet 0.7.x, the latest compatible release is [v0.1.0](https://github.com/MazeMap/Leaflet.TileLayer.PouchDBCached/releases/tag/v0.1.0).
|
||||
|
||||
|
||||
# Usage
|
||||
|
||||
The plugin modifies the core `L.TileLayer` class, so it should be possible to cache any tile layer.
|
||||
|
||||
To use, add the option `useCache` with a value of `true` when instantiating your layer. You probably want to use Leaflet's `crossOrigin` option, like so:
|
||||
|
||||
```
|
||||
var layer = L.tileLayer('https://whatever/{z}/{x}/{y}.png', {
|
||||
maxZoom: 18,
|
||||
|
||||
useCache: true,
|
||||
crossOrigin: true
|
||||
});
|
||||
```
|
||||
|
||||
Options available are as follows:
|
||||
|
||||
* `useCache`: set to true in order to enable the cache. This option must be set at initialization time.
|
||||
* `saveToCache`: Whether to save new tiles to the cache or not. Defaults to true.
|
||||
* `useOnlyCache`: Whether to fetch tiles from the network or not. Defaults to false.
|
||||
* `cacheMaxAge`: Time, in milliseconds, for any given tile to be considered 'fresh'. Tiles older than this value will be re-requested from the network. Defaults to 24 hours.
|
||||
|
||||
New functions available are as follows:
|
||||
* `seed`: Starts seeding the cache for a given bounding box (a `L.LatLngBounds`), and between the two given zoom levels.
|
||||
|
||||
New events available are as follows:
|
||||
|
||||
* `tilecachehit`: Fired when a tile has been found in the tile cache. The event includes data as per http://leafletjs.com/reference.html#tile-event
|
||||
* `tilecachemiss`: Like `tilecachehit`, but is fired when the tile has *not* been found in the cache.
|
||||
* `tilecacheerror`: Fired when there was an error trying to save a tile in the cache. The event data includes:
|
||||
* `tile`: A reference to the failed tile
|
||||
* `error`: The error message, probably related to CORS.
|
||||
* `seedstart`: Fired when a layer cache has started seeding. The event data includes:
|
||||
* `bbox`: bounding box for the seed operation, as per the `L.TileLayer.seed()` function call.
|
||||
* `minZoom` and `maxZoom`: zoom levels the seed operation, as per the `L.TileLayer.seed()` function call.
|
||||
* `queueLength`: (integer) Total number of tiles to be loaded during the seed operation.
|
||||
* `seedend`: Fired when a layer cache has finished seeding.
|
||||
* `seedprogress`: Fired every time a tile is cached during a seed operation
|
||||
* `remainingLength`: (integer) How many tiles are left in the seed queue. Starts with a value of `queueLength` and drops down to zero.
|
||||
|
||||
|
||||
# Cross-Origin Resource Sharing
|
||||
|
||||
Due to the tile images being parsed and stored by the browser (technically, extracting data from a canvas in which a external image has been loaded into), the tiles must come from a tile server which allows CORS (Cross-Origin Resource Sharing) on the tiles. So tiles must have a CORS header allowing them to be loaded in the document where you're using this caching layer.
|
||||
|
||||
In other words: if chrome shows a grey map, and displays CORS-related messages in the console, make sure that your tileserver adds this header to all tiles:
|
||||
|
||||
`Access-Control-Allow-Origin: *`
|
||||
|
||||
|
||||
# Underlying cache structure
|
||||
|
||||
This plugin uses an instance of PouchDB, named `offline-tiles`. PouchDB is a key-value store, so the key is the URL of a tile, and the value is a plain object containing a timestamp and the base64-encoded image.
|
||||
|
||||
|
||||
# License and stuff
|
||||
|
||||
Under MIT license.
|
||||
|
||||
Heavily inspired by https://github.com/tbicr/OfflineMap
|
||||
|
Reference in New Issue
Block a user