UNPKG

ngx.leaflet.offline

Version:

A Leaflet library that downloads map tiles and uses them offline.

143 lines (108 loc) 8.15 kB
# ngx.leaflet.offline [![License: GPLv2](https://img.shields.io/badge/License-GPLv2-blue.svg)](https://opensource.org/licenses/GPL-2.0) [![npm version](https://badge.fury.io/js/ngx.leaflet.offline.svg)](https://badge.fury.io/js/ngx.leaflet.offline) A Leaflet library that downloads map tiles and uses them offline. Check out the demo at https://betoxl.github.io/ngx.leaflet.offline/index.html . Example: https://github.com/BETOXL/offlinemap-angular-example @types https://www.npmjs.com/package/@types/ngx.leaflet.offline ## Inspiration This library was heavily inspired and based on the [leaflet.offline](https://github.com/allartk/leaflet.offline) library by Allart Kooiman. I decided to create a new one because the ideas I had were diverging too much from what ```leaflet.offline``` proposes to do. The biggest change I made was removing the dependency on [localForage](https://github.com/localForage/localForage) and introducing a new parameter that makes you able to give your own implementantion of a database layer to save, retrieve and delete the map tiles however you like as long as it implements the same interface (more on that below). ## Dependencies - [Leaflet](https://github.com/Leaflet/Leaflet) (v1.1.0) ## Install If you use ```npm```, you can install ```ngx.leaflet.offline``` by running: ```npm install ngx.leaflet.offline``` If you don't use a package manager, simply download a file from the ```dist/``` folder and include it in your application. ## Guide ### Database Layer When creating both the ```OfflineControl``` and the ```OfflineLayer```, you need to pass an object that will act as the database layer when saving, retrieving and deleting map tiles. The object **must** implement the following interface. | Method | Parameters | Returns | | ----------- | --------------- | --------------------------------------------------------------------------------------------- | | 'getItem' | key: String | Promise. The result of the promise must be a Blob, File or MediaStream representing the image | | 'saveTiles' | tileUrls: Array | Promise. The result is ignored | | 'clear' | None | Promise. The result is ignored | ### Layer API When creating the ```OfflineLayer```, you need to pass the URL from where the map tiles will be retrieved, the database layer object and the options parameter. There are no special options for the ```OfflineLayer```, they are the same as the [TileLayer options](http://leafletjs.com/reference-1.2.0.html#tilelayer-option) from Leaflet. ### Control API When creating the ```OfflineControl```, you need to pass the ```OfflineLayer```, the database layer object and the options parameter. The options parameter is defined as follows: | Option | Type | Default | Description | | ------------------------ | -------- | -------------- | ---------------------------------------------------------------------------------- | | 'position' | String | 'topleft' | [Control options](http://leafletjs.com/reference-1.2.0.html#control-position) | | 'saveButtonHtml' | String | 'S' | The HTML that will be displayed as the save button | | 'saveButtonTitle' | String | 'Save tiles' | The title that will be used for the save button | | 'removeButtonHtml' | String | 'R' | The HTML that will be displayed as the remove button | | 'removeButtonTitle' | String | 'Remove tiles' | The title that will be used for the remove button | | 'minZoom' | Number | 0 | The save operation won't start when trying to save map tiles below this zoom level | | 'maxZoom' | Number | 19 | The save operation will not save map tiles beyond this zoom level | | 'confirmSavingCallback' | Function | null | A function to be executed before the save operation starts | | 'confirmRemovalCallback' | Function | null | A function to be executed before the remove operation starts | The callbacks should implement the following interface. | Method | Parameters | Returns | | ------------------------- | ------------------------------------------------- | ---------------------------------------------------------------------------- | | 'confirmSavingCallback' | nTilesToSave: Number, continueSaveTiles: Function | Whatever. Remember to call ```continueSaveTiles``` to resume the operation | | 'confirmRemovalCallback' | continueRemoveTiles: Function | Whatever. Remember to call ```continueRemoveTiles``` to resume the operation | ### Events Events fired by the ```OfflineControl``` on the ```OfflineLayer```. Assume that ```tilesDb``` is the database layer object. | Event | Data | Description | | ------------------------------ | ---------------------- | ------------------------------------------------------------------------------- | | 'offline:below-min-zoom-error' | undefined | Fired when trying to save below minimum zoom level | | 'offline:save-start' | {nTilesToSave: Number} | Fired when the save operation starts but before calling ```tilesDb.saveTiles``` | | 'offline:save-end' | undefined | Fired when the promise from ```tilesDb.saveTiles``` finishes successfully | | 'offline:save-error' | {error: Error} | Fired when the promise from ```tilesDb.saveTiles``` finishes with an error | | 'offline:remove-start' | undefined | Fired when the remove operation starts but before calling ```tilesDb.clear``` | | 'offline:remove-end' | undefined | Fired when the promise from ```tilesDb.clear``` finishes successfully | | 'offline:remove-error' | {error: Error} | Fired when the promise from ```tilesDb.clear``` finishes with an error | ## Example Creating the database layer object. ```javascript var tilesDb = { getItem: function (key) { // return Promise that has the image Blob/File/Stream. }, saveTiles: function (tileUrls) { // return Promise. }, clear: function () { // return Promise. } }; ``` Creating the ```OfflineLayer```. ```javascript var map = L.map('map-id'); var offlineLayer = L.tileLayer.offline('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', tilesDb, { attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>', subdomains: 'abc', minZoom: 13, maxZoom: 19, crossOrigin: true }); ``` Creating the ```OfflineControl```. ```javascript var offlineControl = L.control.offline(offlineLayer, tilesDb, { saveButtonHtml: '<i class="fa fa-download" aria-hidden="true"></i>', removeButtonHtml: '<i class="fa fa-trash" aria-hidden="true"></i>', confirmSavingCallback: function (nTilesToSave, continueSaveTiles) { if (window.confirm('Save ' + nTilesToSave + '?')) { continueSaveTiles(); } }, confirmRemovalCallback: function (continueRemoveTiles) { if (window.confirm('Remove all the tiles?')) { continueRemoveTiles(); } }, minZoom: 13, maxZoom: 19 }); ``` Adding both of them to the map. ```javascript offlineLayer.addTo(map); offlineControl.addTo(map); ``` For a more complete example, check the demo code inside the ```gh-pages``` branch.