From 564315a690ac91968c738401b64654f3aa8d9e88 Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Mon, 12 Feb 2018 06:42:52 -0700 Subject: [PATCH] Remove private static members from TileUTFGrid source --- src/ol/source/TileUTFGrid.js | 468 ++++++++++++------------ test/spec/ol/source/tileutfgrid.test.js | 4 +- 2 files changed, 237 insertions(+), 235 deletions(-) diff --git a/src/ol/source/TileUTFGrid.js b/src/ol/source/TileUTFGrid.js index caa243e0c7..f8c08ed28a 100644 --- a/src/ol/source/TileUTFGrid.js +++ b/src/ol/source/TileUTFGrid.js @@ -16,6 +16,239 @@ import TileSource from '../source/Tile.js'; import _ol_tilecoord_ from '../tilecoord.js'; import {createXYZ, extentFromProjection} from '../tilegrid.js'; + +/** + * @constructor + * @extends {ol.Tile} + * @param {ol.TileCoord} tileCoord Tile coordinate. + * @param {ol.TileState} state State. + * @param {string} src Image source URI. + * @param {ol.Extent} extent Extent of the tile. + * @param {boolean} preemptive Load the tile when visible (before it's needed). + * @param {boolean} jsonp Load the tile as a script. + */ +export const CustomTile = function(tileCoord, state, src, extent, preemptive, jsonp) { + + Tile.call(this, tileCoord, state); + + /** + * @private + * @type {string} + */ + this.src_ = src; + + /** + * @private + * @type {ol.Extent} + */ + this.extent_ = extent; + + /** + * @private + * @type {boolean} + */ + this.preemptive_ = preemptive; + + /** + * @private + * @type {Array.} + */ + this.grid_ = null; + + /** + * @private + * @type {Array.} + */ + this.keys_ = null; + + /** + * @private + * @type {Object.|undefined} + */ + this.data_ = null; + + + /** + * @private + * @type {boolean} + */ + this.jsonp_ = jsonp; + +}; +inherits(CustomTile, Tile); + + +/** + * Get the image element for this tile. + * @return {Image} Image. + */ +CustomTile.prototype.getImage = function() { + return null; +}; + + +/** + * Synchronously returns data at given coordinate (if available). + * @param {ol.Coordinate} coordinate Coordinate. + * @return {*} The data. + */ +CustomTile.prototype.getData = function(coordinate) { + if (!this.grid_ || !this.keys_) { + return null; + } + const xRelative = (coordinate[0] - this.extent_[0]) / + (this.extent_[2] - this.extent_[0]); + const yRelative = (coordinate[1] - this.extent_[1]) / + (this.extent_[3] - this.extent_[1]); + + const row = this.grid_[Math.floor((1 - yRelative) * this.grid_.length)]; + + if (typeof row !== 'string') { + return null; + } + + let code = row.charCodeAt(Math.floor(xRelative * row.length)); + if (code >= 93) { + code--; + } + if (code >= 35) { + code--; + } + code -= 32; + + let data = null; + if (code in this.keys_) { + const id = this.keys_[code]; + if (this.data_ && id in this.data_) { + data = this.data_[id]; + } else { + data = id; + } + } + return data; +}; + + +/** + * Calls the callback (synchronously by default) with the available data + * for given coordinate (or `null` if not yet loaded). + * @param {ol.Coordinate} coordinate Coordinate. + * @param {function(this: T, *)} callback Callback. + * @param {T=} opt_this The object to use as `this` in the callback. + * @param {boolean=} opt_request If `true` the callback is always async. + * The tile data is requested if not yet loaded. + * @template T + */ +CustomTile.prototype.forDataAtCoordinate = function(coordinate, callback, opt_this, opt_request) { + if (this.state == TileState.IDLE && opt_request === true) { + listenOnce(this, EventType.CHANGE, function(e) { + callback.call(opt_this, this.getData(coordinate)); + }, this); + this.loadInternal_(); + } else { + if (opt_request === true) { + setTimeout(function() { + callback.call(opt_this, this.getData(coordinate)); + }.bind(this), 0); + } else { + callback.call(opt_this, this.getData(coordinate)); + } + } +}; + + +/** + * @inheritDoc + */ +CustomTile.prototype.getKey = function() { + return this.src_; +}; + + +/** + * @private + */ +CustomTile.prototype.handleError_ = function() { + this.state = TileState.ERROR; + this.changed(); +}; + + +/** + * @param {!UTFGridJSON} json UTFGrid data. + * @private + */ +CustomTile.prototype.handleLoad_ = function(json) { + this.grid_ = json.grid; + this.keys_ = json.keys; + this.data_ = json.data; + + this.state = TileState.EMPTY; + this.changed(); +}; + + +/** + * @private + */ +CustomTile.prototype.loadInternal_ = function() { + if (this.state == TileState.IDLE) { + this.state = TileState.LOADING; + if (this.jsonp_) { + requestJSONP(this.src_, this.handleLoad_.bind(this), + this.handleError_.bind(this)); + } else { + const client = new XMLHttpRequest(); + client.addEventListener('load', this.onXHRLoad_.bind(this)); + client.addEventListener('error', this.onXHRError_.bind(this)); + client.open('GET', this.src_); + client.send(); + } + } +}; + + +/** + * @private + * @param {Event} event The load event. + */ +CustomTile.prototype.onXHRLoad_ = function(event) { + const client = /** @type {XMLHttpRequest} */ (event.target); + // status will be 0 for file:// urls + if (!client.status || client.status >= 200 && client.status < 300) { + let response; + try { + response = /** @type {!UTFGridJSON} */(JSON.parse(client.responseText)); + } catch (err) { + this.handleError_(); + return; + } + this.handleLoad_(response); + } else { + this.handleError_(); + } +}; + + +/** + * @private + * @param {Event} event The error event. + */ +CustomTile.prototype.onXHRError_ = function(event) { + this.handleError_(); +}; + + +/** + * @override + */ +CustomTile.prototype.load = function() { + if (this.preemptive_) { + this.loadInternal_(); + } +}; + + /** * @classdesc * Layer source for UTFGrid interaction data loaded from TileJSON format. @@ -134,7 +367,7 @@ UTFGrid.prototype.forDataAtCoordinateAndResolution = function( if (this.tileGrid) { const tileCoord = this.tileGrid.getTileCoordForCoordAndResolution( coordinate, resolution); - const tile = /** @type {!ol.source.TileUTFGrid.Tile_} */(this.getTile( + const tile = /** @type {!ol.source.CustomTile} */(this.getTile( tileCoord[0], tileCoord[1], tileCoord[2], 1, this.getProjection())); tile.forDataAtCoordinate(coordinate, callback, null, opt_request); } else { @@ -222,7 +455,7 @@ UTFGrid.prototype.getTile = function(z, x, y, pixelRatio, projection) { const urlTileCoord = this.getTileCoordForTileUrlFunction(tileCoord, projection); const tileUrl = this.tileUrlFunction_(urlTileCoord, pixelRatio, projection); - const tile = new UTFGrid.Tile_( + const tile = new CustomTile( tileCoord, tileUrl !== undefined ? TileState.IDLE : TileState.EMPTY, tileUrl !== undefined ? tileUrl : '', @@ -246,235 +479,4 @@ UTFGrid.prototype.useTile = function(z, x, y) { }; -/** - * @constructor - * @extends {ol.Tile} - * @param {ol.TileCoord} tileCoord Tile coordinate. - * @param {ol.TileState} state State. - * @param {string} src Image source URI. - * @param {ol.Extent} extent Extent of the tile. - * @param {boolean} preemptive Load the tile when visible (before it's needed). - * @param {boolean} jsonp Load the tile as a script. - * @private - */ -UTFGrid.Tile_ = function(tileCoord, state, src, extent, preemptive, jsonp) { - - Tile.call(this, tileCoord, state); - - /** - * @private - * @type {string} - */ - this.src_ = src; - - /** - * @private - * @type {ol.Extent} - */ - this.extent_ = extent; - - /** - * @private - * @type {boolean} - */ - this.preemptive_ = preemptive; - - /** - * @private - * @type {Array.} - */ - this.grid_ = null; - - /** - * @private - * @type {Array.} - */ - this.keys_ = null; - - /** - * @private - * @type {Object.|undefined} - */ - this.data_ = null; - - - /** - * @private - * @type {boolean} - */ - this.jsonp_ = jsonp; - -}; -inherits(UTFGrid.Tile_, Tile); - - -/** - * Get the image element for this tile. - * @return {Image} Image. - */ -UTFGrid.Tile_.prototype.getImage = function() { - return null; -}; - - -/** - * Synchronously returns data at given coordinate (if available). - * @param {ol.Coordinate} coordinate Coordinate. - * @return {*} The data. - */ -UTFGrid.Tile_.prototype.getData = function(coordinate) { - if (!this.grid_ || !this.keys_) { - return null; - } - const xRelative = (coordinate[0] - this.extent_[0]) / - (this.extent_[2] - this.extent_[0]); - const yRelative = (coordinate[1] - this.extent_[1]) / - (this.extent_[3] - this.extent_[1]); - - const row = this.grid_[Math.floor((1 - yRelative) * this.grid_.length)]; - - if (typeof row !== 'string') { - return null; - } - - let code = row.charCodeAt(Math.floor(xRelative * row.length)); - if (code >= 93) { - code--; - } - if (code >= 35) { - code--; - } - code -= 32; - - let data = null; - if (code in this.keys_) { - const id = this.keys_[code]; - if (this.data_ && id in this.data_) { - data = this.data_[id]; - } else { - data = id; - } - } - return data; -}; - - -/** - * Calls the callback (synchronously by default) with the available data - * for given coordinate (or `null` if not yet loaded). - * @param {ol.Coordinate} coordinate Coordinate. - * @param {function(this: T, *)} callback Callback. - * @param {T=} opt_this The object to use as `this` in the callback. - * @param {boolean=} opt_request If `true` the callback is always async. - * The tile data is requested if not yet loaded. - * @template T - */ -UTFGrid.Tile_.prototype.forDataAtCoordinate = function(coordinate, callback, opt_this, opt_request) { - if (this.state == TileState.IDLE && opt_request === true) { - listenOnce(this, EventType.CHANGE, function(e) { - callback.call(opt_this, this.getData(coordinate)); - }, this); - this.loadInternal_(); - } else { - if (opt_request === true) { - setTimeout(function() { - callback.call(opt_this, this.getData(coordinate)); - }.bind(this), 0); - } else { - callback.call(opt_this, this.getData(coordinate)); - } - } -}; - - -/** - * @inheritDoc - */ -UTFGrid.Tile_.prototype.getKey = function() { - return this.src_; -}; - - -/** - * @private - */ -UTFGrid.Tile_.prototype.handleError_ = function() { - this.state = TileState.ERROR; - this.changed(); -}; - - -/** - * @param {!UTFGridJSON} json UTFGrid data. - * @private - */ -UTFGrid.Tile_.prototype.handleLoad_ = function(json) { - this.grid_ = json.grid; - this.keys_ = json.keys; - this.data_ = json.data; - - this.state = TileState.EMPTY; - this.changed(); -}; - - -/** - * @private - */ -UTFGrid.Tile_.prototype.loadInternal_ = function() { - if (this.state == TileState.IDLE) { - this.state = TileState.LOADING; - if (this.jsonp_) { - requestJSONP(this.src_, this.handleLoad_.bind(this), - this.handleError_.bind(this)); - } else { - const client = new XMLHttpRequest(); - client.addEventListener('load', this.onXHRLoad_.bind(this)); - client.addEventListener('error', this.onXHRError_.bind(this)); - client.open('GET', this.src_); - client.send(); - } - } -}; - - -/** - * @private - * @param {Event} event The load event. - */ -UTFGrid.Tile_.prototype.onXHRLoad_ = function(event) { - const client = /** @type {XMLHttpRequest} */ (event.target); - // status will be 0 for file:// urls - if (!client.status || client.status >= 200 && client.status < 300) { - let response; - try { - response = /** @type {!UTFGridJSON} */(JSON.parse(client.responseText)); - } catch (err) { - this.handleError_(); - return; - } - this.handleLoad_(response); - } else { - this.handleError_(); - } -}; - - -/** - * @private - * @param {Event} event The error event. - */ -UTFGrid.Tile_.prototype.onXHRError_ = function(event) { - this.handleError_(); -}; - - -/** - * @override - */ -UTFGrid.Tile_.prototype.load = function() { - if (this.preemptive_) { - this.loadInternal_(); - } -}; export default UTFGrid; diff --git a/test/spec/ol/source/tileutfgrid.test.js b/test/spec/ol/source/tileutfgrid.test.js index 9fc18905d8..bf91a917bb 100644 --- a/test/spec/ol/source/tileutfgrid.test.js +++ b/test/spec/ol/source/tileutfgrid.test.js @@ -1,6 +1,6 @@ import {get as getProjection, transformExtent, fromLonLat} from '../../../../src/ol/proj.js'; import TileSource from '../../../../src/ol/source/Tile.js'; -import UTFGrid from '../../../../src/ol/source/TileUTFGrid.js'; +import UTFGrid, {CustomTile} from '../../../../src/ol/source/TileUTFGrid.js'; import TileGrid from '../../../../src/ol/tilegrid/TileGrid.js'; @@ -228,7 +228,7 @@ describe('ol.source.TileUTFGrid', function() { const urlTileCoord = this.getTileCoordForTileUrlFunction(tileCoord, projection); const tileUrl = this.tileUrlFunction_(urlTileCoord, pixelRatio, projection); - const tile = new UTFGrid.Tile_( + const tile = new CustomTile( tileCoord, tileUrl !== undefined ? 0 : 4, // IDLE : EMPTY tileUrl !== undefined ? tileUrl : '',