nakarte

Source code of https://map.sikmir.ru (fork)
git clone git://git.sikmir.ru/nakarte
Log | Files | Refs | LICENSE

commit 1d1f9b32d92f436d0f731e842f507429c1544cb6
parent f54ff92665b2871a10a1820608dddbb5e344eedc
Author: Sergej Orlov <wladimirych@gmail.com>
Date:   Tue, 31 Jan 2017 01:02:52 +0300

[wikimapia] smoother ui while decoding data (return control every 20 ms); fix abort tile load

Diffstat:
Msrc/lib/leaflet.layer.wikimapia/index.js | 2+-
Msrc/lib/leaflet.layer.wikimapia/wikimapia-loader.js | 17+++++++++++------
Msrc/lib/leaflet.layer.wikimapia/wm-utils.js | 12+++++++++++-
Msrc/lib/tiled-data-loader/index.js | 38++++++++++++++++++++------------------
4 files changed, 43 insertions(+), 26 deletions(-)

diff --git a/src/lib/leaflet.layer.wikimapia/index.js b/src/lib/leaflet.layer.wikimapia/index.js @@ -23,7 +23,7 @@ function isPointInPolygon(polygon, p) { L.Wikimapia = L.GridLayer.extend({ options: { tileSize: 1024, - updateWhenIdle: true, + updateWhenIdle: true }, initialize: function(options) { diff --git a/src/lib/leaflet.layer.wikimapia/wikimapia-loader.js b/src/lib/leaflet.layer.wikimapia/wikimapia-loader.js @@ -58,17 +58,22 @@ class WikimapiaLoader extends TiledDataLoader { } processResponse(xhr) { - const tileData = wmUtils.parseTile(xhr.response, this._project); - return { - tileData, - coords: tileData.coords - } + return wmUtils.parseTile(xhr.response, this._project) + .then((tileData) => { + return { + tileData, + coords: tileData.coords + } + } + ); + } calcAdjustment(layerTileCoords, dataTileCoords) { const adjustment = super.calcAdjustment( {x: layerTileCoords.x, y: layerTileCoords.y, z: layerTileCoords.z - 2}, - dataTileCoords); + dataTileCoords + ); if (adjustment) { adjustment.offsetX *= 1024; adjustment.offsetY *= 1024; diff --git a/src/lib/leaflet.layer.wikimapia/wm-utils.js b/src/lib/leaflet.layer.wikimapia/wm-utils.js @@ -115,7 +115,11 @@ function makeCoordsLocal(line, tileCoords, projectFunc) { return localCoords; } -function parseTile(s, projectFunc) { +function asap() { + return new Promise((resolve) => setTimeout(resolve, 0)); +} + +async function parseTile(s, projectFunc) { const tile = {}; const places = tile.places = []; const lines = s.split('\n'); @@ -132,7 +136,13 @@ function parseTile(s, projectFunc) { tile.hasChildren = fields[1] === '1'; //FIXME: ignore some errors + let prevTime = Date.now(); for (let line of lines.slice(2)) { + let curTime = Date.now(); + if (curTime - prevTime > 20) { + await asap(); + prevTime = Date.now(); + } const place = {}; const fields = line.split('|'); if (fields.length < 6) { diff --git a/src/lib/tiled-data-loader/index.js b/src/lib/tiled-data-loader/index.js @@ -78,21 +78,22 @@ class TiledDataLoader { const {url, options} = this.makeRequestData(dataTileCoords); const fetchPromise = this._xhrQueue.put(url, options); // TODO: handle errors - const dataPromise = fetchPromise.then((xhr) => { - const {tileData, coords} = this.processResponse(xhr, dataTileCoords); - this._cache.put(this.makeTileKey(coords), tileData); - delete this._pendingRequests[dataTileKey]; - return { - tileData, - coords - }; - } - ); + const dataPromise = fetchPromise + .then((xhr) => this.processResponse(xhr, dataTileCoords)) + .then(({tileData, coords}) => { + this._cache.put(this.makeTileKey(coords), tileData); + delete this._pendingRequests[dataTileKey]; + return { + tileData, + coords + }; + } + ); const pendingRequest = this._pendingRequests[dataTileKey] = { dataPromise, refCount: 0 }; - pendingRequest.abortLoading = function() { + pendingRequest.abortLoading = () => { pendingRequest.refCount -= 1; if (pendingRequest.refCount < 1) { fetchPromise.abort(); @@ -107,13 +108,14 @@ class TiledDataLoader { return { dataPromise: pendingRequest.dataPromise.then((data) => { - return { - coords: data.coords, - tileData: data.tileData, - adjustment: this.calcAdjustment(layerTileCoords, data.coords) - }; - }), - abortLoading: () => pendingRequest.abortLoading + return { + coords: data.coords, + tileData: data.tileData, + adjustment: this.calcAdjustment(layerTileCoords, data.coords) + }; + } + ), + abortLoading: () => pendingRequest.abortLoading() } }