diff --git a/README.md b/README.md index f7306ef..e85ffaf 100644 --- a/README.md +++ b/README.md @@ -50,29 +50,33 @@ No web browser around? Don't worry - and discover the planet in your console! #### Handling the flow * [`bluebird`](https://github.com/petkaantonov/bluebird) for all the asynchronous [Promise](https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Promise) magic * [`request-promise`](https://github.com/request/request-promise) for promisified HTTP request handling +* [`userhome`](https://github.com/shama/userhome) to determine where to persist downloaded tiles ### TODOs * MapSCII * [ ] CLI support - * [ ] global linking for npm install -g + * [X] global linking for npm install -g * [ ] startup parameters + * TileSource + * [ ] VectorTile + * [ ] MBTile + * [ ] Tileserver * [ ] Style * [ ] center position * [ ] POI filter? - * [ ] VectorTile - * [ ] MBTile - * [ ] Tileserver - * [ ] mapscii-server - * [ ] telnet - * [ ] ssh * [ ] Viewport - * [x] start with zoom level which shows full vector tile + * [x] start with zoom level which shows full + * [X] world + * [ ] vector tile * [X] boundary based on current zoom & size * [X] determain tiles to show * [X] zoom while keeping center * [ ] calculate tile areas * [X] center based on mercator * [x] handle console resize + * [ ] mapscii-server + * [ ] telnet + * [ ] ssh * [x] handle console resize * [ ] mouse control * [x] accurate mouse drag&drop with instant update @@ -116,7 +120,7 @@ No web browser around? Don't worry - and discover the planet in your console! * [ ] from single vector-tile * [x] from local mbtiles * [x] from remote url - * [ ] permanent caching of received files + * [x] permanent caching of received files ## License #### The MIT License (MIT) diff --git a/package.json b/package.json index 0a289c0..c166ea1 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "sphericalmercator": "^1.0.5", "term-mouse": "^0.1.1", "tilebelt": "^1.0.1", + "userhome": "^1.0.0", "vector-tile": "^1.3.0", "x256": "0.0.2" } diff --git a/src/Renderer.coffee b/src/Renderer.coffee index f08f755..08ed3b9 100644 --- a/src/Renderer.coffee +++ b/src/Renderer.coffee @@ -7,7 +7,6 @@ x256 = require 'x256' mercator = new (require('sphericalmercator'))() tilebelt = require 'tilebelt' -MBTiles = require 'mbtiles' Promise = require 'bluebird' Canvas = require './Canvas' diff --git a/src/TileSource.coffee b/src/TileSource.coffee index d4c70cc..a99ba0b 100644 --- a/src/TileSource.coffee +++ b/src/TileSource.coffee @@ -9,13 +9,17 @@ Promise = require 'bluebird' MBTiles = require 'mbtiles' - +userhome = require 'userhome' request = require 'request' rp = require 'request-promise' +fs = require 'fs' Tile = require './Tile' module.exports = class TileSource + config: + persistDownloadedTiles: true + cache: {} modes: MBTiles: 1 @@ -28,6 +32,8 @@ module.exports = class TileSource init: (@source) -> if @source.startsWith "http" + @_initPersistence() if @config.persistDownloadedTiles + @mode = @modes.HTTP else if @source.endsWith ".mbtiles" @@ -57,9 +63,18 @@ module.exports = class TileSource when @modes.HTTP then @_getHTTP z, x, y _getHTTP: (z, x, y) -> - rp - uri: @source+[z,x,y].join("/")+".pbf" - encoding: null + promise = + if @config.persistDownloadedTiles and tile = @_getPersited z, x, y + Promise.resolve tile + else + rp + uri: @source+[z,x,y].join("/")+".pbf" + encoding: null + .then (buffer) => + @_persistTile z, x, y, buffer if @config.persistDownloadedTiles + buffer + + promise .then (buffer) => @_createTile z, x, y, buffer @@ -72,3 +87,29 @@ module.exports = class TileSource _createTile: (z, x, y, buffer) -> tile = @cache[[z,x,y].join("-")] = new Tile() tile.load buffer + + _initPersistence: -> + try + @_createFolder userhome ".mapscii" + @_createFolder userhome ".mapscii", "cache" + catch error + @config.persistDownloadedTiles = false + return + + _persistTile: (z, x, y, buffer) -> + zoom = z.toString() + @_createFolder userhome ".mapscii", "cache", zoom + fs.writeFile userhome(".mapscii", "cache", zoom, "#{x}-#{y}.pbf"), buffer + + _getPersited: (z, x, y) -> + try + fs.readFileSync userhome ".mapscii", "cache", z.toString(), "#{x}-#{y}.pbf" + catch error + false + + _createFolder: (path) -> + try + fs.mkdirSync path + true + catch e + e.code is "EEXIST"