Manual class transform
This commit is contained in:
@@ -11,29 +11,32 @@ import {VERSION, inherits} from './util.js';
|
||||
* @extends {Error}
|
||||
* @param {number} code Error code.
|
||||
*/
|
||||
const AssertionError = function(code) {
|
||||
class AssertionError {
|
||||
|
||||
const path = VERSION.split('-')[0];
|
||||
constructor(code) {
|
||||
const path = VERSION.split('-')[0];
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
this.message = 'Assertion failed. See https://openlayers.org/en/' + path +
|
||||
'/doc/errors/#' + code + ' for details.';
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
this.message = 'Assertion failed. See https://openlayers.org/en/' + path +
|
||||
'/doc/errors/#' + code + ' for details.';
|
||||
|
||||
/**
|
||||
* Error code. The meaning of the code can be found on
|
||||
* {@link https://openlayers.org/en/latest/doc/errors/} (replace `latest` with
|
||||
* the version found in the OpenLayers script's header comment if a version
|
||||
* other than the latest is used).
|
||||
* @type {number}
|
||||
* @api
|
||||
*/
|
||||
this.code = code;
|
||||
/**
|
||||
* Error code. The meaning of the code can be found on
|
||||
* {@link https://openlayers.org/en/latest/doc/errors/} (replace `latest` with
|
||||
* the version found in the OpenLayers script's header comment if a version
|
||||
* other than the latest is used).
|
||||
* @type {number}
|
||||
* @api
|
||||
*/
|
||||
this.code = code;
|
||||
|
||||
this.name = 'AssertionError';
|
||||
this.name = 'AssertionError';
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inherits(AssertionError, Error);
|
||||
|
||||
|
||||
@@ -27,18 +27,21 @@ const Property = {
|
||||
* @param {module:ol/CollectionEventType} type Type.
|
||||
* @param {*=} opt_element Element.
|
||||
*/
|
||||
export const CollectionEvent = function(type, opt_element) {
|
||||
export class CollectionEvent {
|
||||
|
||||
Event.call(this, type);
|
||||
constructor(type, opt_element) {
|
||||
Event.call(this, type);
|
||||
|
||||
/**
|
||||
* The element that is added to or removed from the collection.
|
||||
* @type {*}
|
||||
* @api
|
||||
*/
|
||||
this.element = opt_element;
|
||||
/**
|
||||
* The element that is added to or removed from the collection.
|
||||
* @type {*}
|
||||
* @api
|
||||
*/
|
||||
this.element = opt_element;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inherits(CollectionEvent, Event);
|
||||
|
||||
|
||||
@@ -14,19 +14,23 @@ import MapBrowserEvent from './MapBrowserEvent.js';
|
||||
* @param {boolean=} opt_dragging Is the map currently being dragged?
|
||||
* @param {?module:ol/PluggableMap~FrameState=} opt_frameState Frame state.
|
||||
*/
|
||||
const MapBrowserPointerEvent = function(type, map, pointerEvent, opt_dragging,
|
||||
opt_frameState) {
|
||||
class MapBrowserPointerEvent {
|
||||
|
||||
MapBrowserEvent.call(this, type, map, pointerEvent.originalEvent, opt_dragging,
|
||||
opt_frameState);
|
||||
constructor(type, map, pointerEvent, opt_dragging, opt_frameState) {
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {module:ol/pointer/PointerEvent}
|
||||
*/
|
||||
this.pointerEvent = pointerEvent;
|
||||
MapBrowserEvent.call(this, type, map, pointerEvent.originalEvent, opt_dragging,
|
||||
opt_frameState);
|
||||
|
||||
};
|
||||
/**
|
||||
* @const
|
||||
* @type {module:ol/pointer/PointerEvent}
|
||||
*/
|
||||
this.pointerEvent = pointerEvent;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inherits(MapBrowserPointerEvent, MapBrowserEvent);
|
||||
|
||||
export default MapBrowserPointerEvent;
|
||||
|
||||
@@ -15,25 +15,30 @@ import Event from './events/Event.js';
|
||||
* @param {module:ol/PluggableMap} map Map.
|
||||
* @param {?module:ol/PluggableMap~FrameState=} opt_frameState Frame state.
|
||||
*/
|
||||
const MapEvent = function(type, map, opt_frameState) {
|
||||
class MapEvent {
|
||||
|
||||
Event.call(this, type);
|
||||
constructor(type, map, opt_frameState) {
|
||||
|
||||
/**
|
||||
* The map where the event occurred.
|
||||
* @type {module:ol/PluggableMap}
|
||||
* @api
|
||||
*/
|
||||
this.map = map;
|
||||
Event.call(this, type);
|
||||
|
||||
/**
|
||||
* The frame state at the time of the event.
|
||||
* @type {?module:ol/PluggableMap~FrameState}
|
||||
* @api
|
||||
*/
|
||||
this.frameState = opt_frameState !== undefined ? opt_frameState : null;
|
||||
/**
|
||||
* The map where the event occurred.
|
||||
* @type {module:ol/PluggableMap}
|
||||
* @api
|
||||
*/
|
||||
this.map = map;
|
||||
|
||||
};
|
||||
/**
|
||||
* The frame state at the time of the event.
|
||||
* @type {?module:ol/PluggableMap~FrameState}
|
||||
* @api
|
||||
*/
|
||||
this.frameState = opt_frameState !== undefined ? opt_frameState : null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inherits(MapEvent, Event);
|
||||
|
||||
export default MapEvent;
|
||||
|
||||
@@ -19,25 +19,30 @@ import {assign} from './obj.js';
|
||||
* @extends {module:ol/events/Event}
|
||||
* @constructor
|
||||
*/
|
||||
const ObjectEvent = function(type, key, oldValue) {
|
||||
Event.call(this, type);
|
||||
class ObjectEvent {
|
||||
|
||||
/**
|
||||
* The name of the property whose value is changing.
|
||||
* @type {string}
|
||||
* @api
|
||||
*/
|
||||
this.key = key;
|
||||
constructor(type, key, oldValue) {
|
||||
Event.call(this, type);
|
||||
|
||||
/**
|
||||
* The old value. To get the new value use `e.target.get(e.key)` where
|
||||
* `e` is the event object.
|
||||
* @type {*}
|
||||
* @api
|
||||
*/
|
||||
this.oldValue = oldValue;
|
||||
/**
|
||||
* The name of the property whose value is changing.
|
||||
* @type {string}
|
||||
* @api
|
||||
*/
|
||||
this.key = key;
|
||||
|
||||
/**
|
||||
* The old value. To get the new value use `e.target.get(e.key)` where
|
||||
* `e` is the event object.
|
||||
* @type {*}
|
||||
* @api
|
||||
*/
|
||||
this.oldValue = oldValue;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
inherits(ObjectEvent, Event);
|
||||
|
||||
|
||||
|
||||
375
src/ol/Tile.js
375
src/ol/Tile.js
@@ -51,214 +51,215 @@ import EventType from './events/EventType.js';
|
||||
* @param {module:ol/TileState} state State.
|
||||
* @param {module:ol/Tile~Options=} opt_options Tile options.
|
||||
*/
|
||||
const Tile = function(tileCoord, state, opt_options) {
|
||||
EventTarget.call(this);
|
||||
class Tile {
|
||||
constructor(tileCoord, state, opt_options) {
|
||||
EventTarget.call(this);
|
||||
|
||||
const options = opt_options ? opt_options : {};
|
||||
const options = opt_options ? opt_options : {};
|
||||
|
||||
/**
|
||||
* @type {module:ol/tilecoord~TileCoord}
|
||||
*/
|
||||
this.tileCoord = tileCoord;
|
||||
/**
|
||||
* @type {module:ol/tilecoord~TileCoord}
|
||||
*/
|
||||
this.tileCoord = tileCoord;
|
||||
|
||||
/**
|
||||
* @protected
|
||||
* @type {module:ol/TileState}
|
||||
*/
|
||||
this.state = state;
|
||||
|
||||
/**
|
||||
* An "interim" tile for this tile. The interim tile may be used while this
|
||||
* one is loading, for "smooth" transitions when changing params/dimensions
|
||||
* on the source.
|
||||
* @type {module:ol/Tile}
|
||||
*/
|
||||
this.interimTile = null;
|
||||
|
||||
/**
|
||||
* A key assigned to the tile. This is used by the tile source to determine
|
||||
* if this tile can effectively be used, or if a new tile should be created
|
||||
* and this one be used as an interim tile for this new tile.
|
||||
* @type {string}
|
||||
*/
|
||||
this.key = '';
|
||||
|
||||
/**
|
||||
* The duration for the opacity transition.
|
||||
* @type {number}
|
||||
*/
|
||||
this.transition_ = options.transition === undefined ? 250 : options.transition;
|
||||
|
||||
/**
|
||||
* Lookup of start times for rendering transitions. If the start time is
|
||||
* equal to -1, the transition is complete.
|
||||
* @type {Object.<number, number>}
|
||||
*/
|
||||
this.transitionStarts_ = {};
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @protected
|
||||
* @type {module:ol/TileState}
|
||||
*/
|
||||
this.state = state;
|
||||
changed() {
|
||||
this.dispatchEvent(EventType.CHANGE);
|
||||
}
|
||||
|
||||
/**
|
||||
* An "interim" tile for this tile. The interim tile may be used while this
|
||||
* one is loading, for "smooth" transitions when changing params/dimensions
|
||||
* on the source.
|
||||
* @type {module:ol/Tile}
|
||||
* @return {string} Key.
|
||||
*/
|
||||
this.interimTile = null;
|
||||
getKey() {
|
||||
return this.key + '/' + this.tileCoord;
|
||||
}
|
||||
|
||||
/**
|
||||
* A key assigned to the tile. This is used by the tile source to determine
|
||||
* if this tile can effectively be used, or if a new tile should be created
|
||||
* and this one be used as an interim tile for this new tile.
|
||||
* @type {string}
|
||||
* Get the interim tile most suitable for rendering using the chain of interim
|
||||
* tiles. This corresponds to the most recent tile that has been loaded, if no
|
||||
* such tile exists, the original tile is returned.
|
||||
* @return {!module:ol/Tile} Best tile for rendering.
|
||||
*/
|
||||
this.key = '';
|
||||
getInterimTile() {
|
||||
if (!this.interimTile) {
|
||||
//empty chain
|
||||
return this;
|
||||
}
|
||||
let tile = this.interimTile;
|
||||
|
||||
// find the first loaded tile and return it. Since the chain is sorted in
|
||||
// decreasing order of creation time, there is no need to search the remainder
|
||||
// of the list (all those tiles correspond to older requests and will be
|
||||
// cleaned up by refreshInterimChain)
|
||||
do {
|
||||
if (tile.getState() == TileState.LOADED) {
|
||||
return tile;
|
||||
}
|
||||
tile = tile.interimTile;
|
||||
} while (tile);
|
||||
|
||||
// we can not find a better tile
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The duration for the opacity transition.
|
||||
* @type {number}
|
||||
* Goes through the chain of interim tiles and discards sections of the chain
|
||||
* that are no longer relevant.
|
||||
*/
|
||||
this.transition_ = options.transition === undefined ? 250 : options.transition;
|
||||
refreshInterimChain() {
|
||||
if (!this.interimTile) {
|
||||
return;
|
||||
}
|
||||
|
||||
let tile = this.interimTile;
|
||||
let prev = this;
|
||||
|
||||
do {
|
||||
if (tile.getState() == TileState.LOADED) {
|
||||
//we have a loaded tile, we can discard the rest of the list
|
||||
//we would could abort any LOADING tile request
|
||||
//older than this tile (i.e. any LOADING tile following this entry in the chain)
|
||||
tile.interimTile = null;
|
||||
break;
|
||||
} else if (tile.getState() == TileState.LOADING) {
|
||||
//keep this LOADING tile any loaded tiles later in the chain are
|
||||
//older than this tile, so we're still interested in the request
|
||||
prev = tile;
|
||||
} else if (tile.getState() == TileState.IDLE) {
|
||||
//the head of the list is the most current tile, we don't need
|
||||
//to start any other requests for this chain
|
||||
prev.interimTile = tile.interimTile;
|
||||
} else {
|
||||
prev = tile;
|
||||
}
|
||||
tile = prev.interimTile;
|
||||
} while (tile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup of start times for rendering transitions. If the start time is
|
||||
* equal to -1, the transition is complete.
|
||||
* @type {Object.<number, number>}
|
||||
* Get the tile coordinate for this tile.
|
||||
* @return {module:ol/tilecoord~TileCoord} The tile coordinate.
|
||||
* @api
|
||||
*/
|
||||
this.transitionStarts_ = {};
|
||||
getTileCoord() {
|
||||
return this.tileCoord;
|
||||
}
|
||||
|
||||
};
|
||||
/**
|
||||
* @return {module:ol/TileState} State.
|
||||
*/
|
||||
getState() {
|
||||
return this.state;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {module:ol/TileState} state State.
|
||||
*/
|
||||
setState(state) {
|
||||
this.state = state;
|
||||
this.changed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the image or retry if loading previously failed.
|
||||
* Loading is taken care of by the tile queue, and calling this method is
|
||||
* only needed for preloading or for reloading in case of an error.
|
||||
* @abstract
|
||||
* @api
|
||||
*/
|
||||
load() {}
|
||||
|
||||
/**
|
||||
* Get the alpha value for rendering.
|
||||
* @param {number} id An id for the renderer.
|
||||
* @param {number} time The render frame time.
|
||||
* @return {number} A number between 0 and 1.
|
||||
*/
|
||||
getAlpha(id, time) {
|
||||
if (!this.transition_) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
let start = this.transitionStarts_[id];
|
||||
if (!start) {
|
||||
start = time;
|
||||
this.transitionStarts_[id] = start;
|
||||
} else if (start === -1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
const delta = time - start + (1000 / 60); // avoid rendering at 0
|
||||
if (delta >= this.transition_) {
|
||||
return 1;
|
||||
}
|
||||
return easeIn(delta / this.transition_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a tile is in an alpha transition. A tile is considered in
|
||||
* transition if tile.getAlpha() has not yet been called or has been called
|
||||
* and returned 1.
|
||||
* @param {number} id An id for the renderer.
|
||||
* @return {boolean} The tile is in transition.
|
||||
*/
|
||||
inTransition(id) {
|
||||
if (!this.transition_) {
|
||||
return false;
|
||||
}
|
||||
return this.transitionStarts_[id] !== -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark a transition as complete.
|
||||
* @param {number} id An id for the renderer.
|
||||
*/
|
||||
endTransition(id) {
|
||||
if (this.transition_) {
|
||||
this.transitionStarts_[id] = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inherits(Tile, EventTarget);
|
||||
|
||||
|
||||
/**
|
||||
* @protected
|
||||
*/
|
||||
Tile.prototype.changed = function() {
|
||||
this.dispatchEvent(EventType.CHANGE);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {string} Key.
|
||||
*/
|
||||
Tile.prototype.getKey = function() {
|
||||
return this.key + '/' + this.tileCoord;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the interim tile most suitable for rendering using the chain of interim
|
||||
* tiles. This corresponds to the most recent tile that has been loaded, if no
|
||||
* such tile exists, the original tile is returned.
|
||||
* @return {!module:ol/Tile} Best tile for rendering.
|
||||
*/
|
||||
Tile.prototype.getInterimTile = function() {
|
||||
if (!this.interimTile) {
|
||||
//empty chain
|
||||
return this;
|
||||
}
|
||||
let tile = this.interimTile;
|
||||
|
||||
// find the first loaded tile and return it. Since the chain is sorted in
|
||||
// decreasing order of creation time, there is no need to search the remainder
|
||||
// of the list (all those tiles correspond to older requests and will be
|
||||
// cleaned up by refreshInterimChain)
|
||||
do {
|
||||
if (tile.getState() == TileState.LOADED) {
|
||||
return tile;
|
||||
}
|
||||
tile = tile.interimTile;
|
||||
} while (tile);
|
||||
|
||||
// we can not find a better tile
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Goes through the chain of interim tiles and discards sections of the chain
|
||||
* that are no longer relevant.
|
||||
*/
|
||||
Tile.prototype.refreshInterimChain = function() {
|
||||
if (!this.interimTile) {
|
||||
return;
|
||||
}
|
||||
|
||||
let tile = this.interimTile;
|
||||
let prev = this;
|
||||
|
||||
do {
|
||||
if (tile.getState() == TileState.LOADED) {
|
||||
//we have a loaded tile, we can discard the rest of the list
|
||||
//we would could abort any LOADING tile request
|
||||
//older than this tile (i.e. any LOADING tile following this entry in the chain)
|
||||
tile.interimTile = null;
|
||||
break;
|
||||
} else if (tile.getState() == TileState.LOADING) {
|
||||
//keep this LOADING tile any loaded tiles later in the chain are
|
||||
//older than this tile, so we're still interested in the request
|
||||
prev = tile;
|
||||
} else if (tile.getState() == TileState.IDLE) {
|
||||
//the head of the list is the most current tile, we don't need
|
||||
//to start any other requests for this chain
|
||||
prev.interimTile = tile.interimTile;
|
||||
} else {
|
||||
prev = tile;
|
||||
}
|
||||
tile = prev.interimTile;
|
||||
} while (tile);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the tile coordinate for this tile.
|
||||
* @return {module:ol/tilecoord~TileCoord} The tile coordinate.
|
||||
* @api
|
||||
*/
|
||||
Tile.prototype.getTileCoord = function() {
|
||||
return this.tileCoord;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {module:ol/TileState} State.
|
||||
*/
|
||||
Tile.prototype.getState = function() {
|
||||
return this.state;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {module:ol/TileState} state State.
|
||||
*/
|
||||
Tile.prototype.setState = function(state) {
|
||||
this.state = state;
|
||||
this.changed();
|
||||
};
|
||||
|
||||
/**
|
||||
* Load the image or retry if loading previously failed.
|
||||
* Loading is taken care of by the tile queue, and calling this method is
|
||||
* only needed for preloading or for reloading in case of an error.
|
||||
* @abstract
|
||||
* @api
|
||||
*/
|
||||
Tile.prototype.load = function() {};
|
||||
|
||||
/**
|
||||
* Get the alpha value for rendering.
|
||||
* @param {number} id An id for the renderer.
|
||||
* @param {number} time The render frame time.
|
||||
* @return {number} A number between 0 and 1.
|
||||
*/
|
||||
Tile.prototype.getAlpha = function(id, time) {
|
||||
if (!this.transition_) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
let start = this.transitionStarts_[id];
|
||||
if (!start) {
|
||||
start = time;
|
||||
this.transitionStarts_[id] = start;
|
||||
} else if (start === -1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
const delta = time - start + (1000 / 60); // avoid rendering at 0
|
||||
if (delta >= this.transition_) {
|
||||
return 1;
|
||||
}
|
||||
return easeIn(delta / this.transition_);
|
||||
};
|
||||
|
||||
/**
|
||||
* Determine if a tile is in an alpha transition. A tile is considered in
|
||||
* transition if tile.getAlpha() has not yet been called or has been called
|
||||
* and returned 1.
|
||||
* @param {number} id An id for the renderer.
|
||||
* @return {boolean} The tile is in transition.
|
||||
*/
|
||||
Tile.prototype.inTransition = function(id) {
|
||||
if (!this.transition_) {
|
||||
return false;
|
||||
}
|
||||
return this.transitionStarts_[id] !== -1;
|
||||
};
|
||||
|
||||
/**
|
||||
* Mark a transition as complete.
|
||||
* @param {number} id An id for the renderer.
|
||||
*/
|
||||
Tile.prototype.endTransition = function(id) {
|
||||
if (this.transition_) {
|
||||
this.transitionStarts_[id] = -1;
|
||||
}
|
||||
};
|
||||
export default Tile;
|
||||
|
||||
@@ -11,46 +11,48 @@ import {fromKey, getKey} from './tilecoord.js';
|
||||
* @param {number=} opt_highWaterMark High water mark.
|
||||
* @struct
|
||||
*/
|
||||
const TileCache = function(opt_highWaterMark) {
|
||||
class TileCache {
|
||||
constructor(opt_highWaterMark) {
|
||||
|
||||
LRUCache.call(this, opt_highWaterMark);
|
||||
LRUCache.call(this, opt_highWaterMark);
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!Object.<string, module:ol/TileRange>} usedTiles Used tiles.
|
||||
*/
|
||||
expireCache(usedTiles) {
|
||||
while (this.canExpireCache()) {
|
||||
const tile = this.peekLast();
|
||||
const zKey = tile.tileCoord[0].toString();
|
||||
if (zKey in usedTiles && usedTiles[zKey].contains(tile.tileCoord)) {
|
||||
break;
|
||||
} else {
|
||||
this.pop().dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prune all tiles from the cache that don't have the same z as the newest tile.
|
||||
*/
|
||||
pruneExceptNewestZ() {
|
||||
if (this.getCount() === 0) {
|
||||
return;
|
||||
}
|
||||
const key = this.peekFirstKey();
|
||||
const tileCoord = fromKey(key);
|
||||
const z = tileCoord[0];
|
||||
this.forEach(function(tile) {
|
||||
if (tile.tileCoord[0] !== z) {
|
||||
this.remove(getKey(tile.tileCoord));
|
||||
tile.dispose();
|
||||
}
|
||||
}, this);
|
||||
}
|
||||
}
|
||||
|
||||
inherits(TileCache, LRUCache);
|
||||
|
||||
|
||||
/**
|
||||
* @param {!Object.<string, module:ol/TileRange>} usedTiles Used tiles.
|
||||
*/
|
||||
TileCache.prototype.expireCache = function(usedTiles) {
|
||||
while (this.canExpireCache()) {
|
||||
const tile = this.peekLast();
|
||||
const zKey = tile.tileCoord[0].toString();
|
||||
if (zKey in usedTiles && usedTiles[zKey].contains(tile.tileCoord)) {
|
||||
break;
|
||||
} else {
|
||||
this.pop().dispose();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Prune all tiles from the cache that don't have the same z as the newest tile.
|
||||
*/
|
||||
TileCache.prototype.pruneExceptNewestZ = function() {
|
||||
if (this.getCount() === 0) {
|
||||
return;
|
||||
}
|
||||
const key = this.peekFirstKey();
|
||||
const tileCoord = fromKey(key);
|
||||
const z = tileCoord[0];
|
||||
this.forEach(function(tile) {
|
||||
if (tile.tileCoord[0] !== z) {
|
||||
this.remove(getKey(tile.tileCoord));
|
||||
tile.dispose();
|
||||
}
|
||||
}, this);
|
||||
};
|
||||
export default TileCache;
|
||||
|
||||
@@ -22,115 +22,115 @@ import PriorityQueue from './structs/PriorityQueue.js';
|
||||
* Function called on each tile change event.
|
||||
* @struct
|
||||
*/
|
||||
const TileQueue = function(tilePriorityFunction, tileChangeCallback) {
|
||||
class TileQueue {
|
||||
constructor(tilePriorityFunction, tileChangeCallback) {
|
||||
|
||||
PriorityQueue.call(
|
||||
this,
|
||||
/**
|
||||
* @param {Array} element Element.
|
||||
* @return {number} Priority.
|
||||
*/
|
||||
function(element) {
|
||||
return tilePriorityFunction.apply(null, element);
|
||||
},
|
||||
/**
|
||||
* @param {Array} element Element.
|
||||
* @return {string} Key.
|
||||
*/
|
||||
function(element) {
|
||||
return (/** @type {module:ol/Tile} */ (element[0]).getKey());
|
||||
});
|
||||
|
||||
PriorityQueue.call(
|
||||
this,
|
||||
/**
|
||||
* @param {Array} element Element.
|
||||
* @return {number} Priority.
|
||||
* @private
|
||||
* @type {function(): ?}
|
||||
*/
|
||||
function(element) {
|
||||
return tilePriorityFunction.apply(null, element);
|
||||
},
|
||||
this.tileChangeCallback_ = tileChangeCallback;
|
||||
|
||||
/**
|
||||
* @param {Array} element Element.
|
||||
* @return {string} Key.
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
function(element) {
|
||||
return (/** @type {module:ol/Tile} */ (element[0]).getKey());
|
||||
});
|
||||
this.tilesLoading_ = 0;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {!Object.<string,boolean>}
|
||||
*/
|
||||
this.tilesLoadingKeys_ = {};
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {function(): ?}
|
||||
* @inheritDoc
|
||||
*/
|
||||
this.tileChangeCallback_ = tileChangeCallback;
|
||||
enqueue(element) {
|
||||
const added = PriorityQueue.prototype.enqueue.call(this, element);
|
||||
if (added) {
|
||||
const tile = element[0];
|
||||
listen(tile, EventType.CHANGE, this.handleTileChange, this);
|
||||
}
|
||||
return added;
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
* @return {number} Number of tiles loading.
|
||||
*/
|
||||
this.tilesLoading_ = 0;
|
||||
getTilesLoading() {
|
||||
return this.tilesLoading_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {!Object.<string,boolean>}
|
||||
* @param {module:ol/events/Event} event Event.
|
||||
* @protected
|
||||
*/
|
||||
this.tilesLoadingKeys_ = {};
|
||||
handleTileChange(event) {
|
||||
const tile = /** @type {module:ol/Tile} */ (event.target);
|
||||
const state = tile.getState();
|
||||
if (state === TileState.LOADED || state === TileState.ERROR ||
|
||||
state === TileState.EMPTY || state === TileState.ABORT) {
|
||||
unlisten(tile, EventType.CHANGE, this.handleTileChange, this);
|
||||
const tileKey = tile.getKey();
|
||||
if (tileKey in this.tilesLoadingKeys_) {
|
||||
delete this.tilesLoadingKeys_[tileKey];
|
||||
--this.tilesLoading_;
|
||||
}
|
||||
this.tileChangeCallback_();
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
/**
|
||||
* @param {number} maxTotalLoading Maximum number tiles to load simultaneously.
|
||||
* @param {number} maxNewLoads Maximum number of new tiles to load.
|
||||
*/
|
||||
loadMoreTiles(maxTotalLoading, maxNewLoads) {
|
||||
let newLoads = 0;
|
||||
let abortedTiles = false;
|
||||
let state, tile, tileKey;
|
||||
while (this.tilesLoading_ < maxTotalLoading && newLoads < maxNewLoads &&
|
||||
this.getCount() > 0) {
|
||||
tile = /** @type {module:ol/Tile} */ (this.dequeue()[0]);
|
||||
tileKey = tile.getKey();
|
||||
state = tile.getState();
|
||||
if (state === TileState.ABORT) {
|
||||
abortedTiles = true;
|
||||
} else if (state === TileState.IDLE && !(tileKey in this.tilesLoadingKeys_)) {
|
||||
this.tilesLoadingKeys_[tileKey] = true;
|
||||
++this.tilesLoading_;
|
||||
++newLoads;
|
||||
tile.load();
|
||||
}
|
||||
}
|
||||
if (newLoads === 0 && abortedTiles) {
|
||||
// Do not stop the render loop when all wanted tiles were aborted due to
|
||||
// a small, saturated tile cache.
|
||||
this.tileChangeCallback_();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inherits(TileQueue, PriorityQueue);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
TileQueue.prototype.enqueue = function(element) {
|
||||
const added = PriorityQueue.prototype.enqueue.call(this, element);
|
||||
if (added) {
|
||||
const tile = element[0];
|
||||
listen(tile, EventType.CHANGE, this.handleTileChange, this);
|
||||
}
|
||||
return added;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} Number of tiles loading.
|
||||
*/
|
||||
TileQueue.prototype.getTilesLoading = function() {
|
||||
return this.tilesLoading_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {module:ol/events/Event} event Event.
|
||||
* @protected
|
||||
*/
|
||||
TileQueue.prototype.handleTileChange = function(event) {
|
||||
const tile = /** @type {module:ol/Tile} */ (event.target);
|
||||
const state = tile.getState();
|
||||
if (state === TileState.LOADED || state === TileState.ERROR ||
|
||||
state === TileState.EMPTY || state === TileState.ABORT) {
|
||||
unlisten(tile, EventType.CHANGE, this.handleTileChange, this);
|
||||
const tileKey = tile.getKey();
|
||||
if (tileKey in this.tilesLoadingKeys_) {
|
||||
delete this.tilesLoadingKeys_[tileKey];
|
||||
--this.tilesLoading_;
|
||||
}
|
||||
this.tileChangeCallback_();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} maxTotalLoading Maximum number tiles to load simultaneously.
|
||||
* @param {number} maxNewLoads Maximum number of new tiles to load.
|
||||
*/
|
||||
TileQueue.prototype.loadMoreTiles = function(maxTotalLoading, maxNewLoads) {
|
||||
let newLoads = 0;
|
||||
let abortedTiles = false;
|
||||
let state, tile, tileKey;
|
||||
while (this.tilesLoading_ < maxTotalLoading && newLoads < maxNewLoads &&
|
||||
this.getCount() > 0) {
|
||||
tile = /** @type {module:ol/Tile} */ (this.dequeue()[0]);
|
||||
tileKey = tile.getKey();
|
||||
state = tile.getState();
|
||||
if (state === TileState.ABORT) {
|
||||
abortedTiles = true;
|
||||
} else if (state === TileState.IDLE && !(tileKey in this.tilesLoadingKeys_)) {
|
||||
this.tilesLoadingKeys_[tileKey] = true;
|
||||
++this.tilesLoading_;
|
||||
++newLoads;
|
||||
tile.load();
|
||||
}
|
||||
}
|
||||
if (newLoads === 0 && abortedTiles) {
|
||||
// Do not stop the render loop when all wanted tiles were aborted due to
|
||||
// a small, saturated tile cache.
|
||||
this.tileChangeCallback_();
|
||||
}
|
||||
};
|
||||
export default TileQueue;
|
||||
|
||||
@@ -12,29 +12,116 @@
|
||||
* @param {number} maxY Maximum Y.
|
||||
* @struct
|
||||
*/
|
||||
const TileRange = function(minX, maxX, minY, maxY) {
|
||||
class TileRange {
|
||||
constructor(minX, maxX, minY, maxY) {
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.minX = minX;
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.minX = minX;
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.maxX = maxX;
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.maxX = maxX;
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.minY = minY;
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.minY = minY;
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.maxY = maxY;
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.maxY = maxY;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {module:ol/tilecoord~TileCoord} tileCoord Tile coordinate.
|
||||
* @return {boolean} Contains tile coordinate.
|
||||
*/
|
||||
contains(tileCoord) {
|
||||
return this.containsXY(tileCoord[1], tileCoord[2]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {module:ol/TileRange} tileRange Tile range.
|
||||
* @return {boolean} Contains.
|
||||
*/
|
||||
containsTileRange(tileRange) {
|
||||
return this.minX <= tileRange.minX && tileRange.maxX <= this.maxX &&
|
||||
this.minY <= tileRange.minY && tileRange.maxY <= this.maxY;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} x Tile coordinate x.
|
||||
* @param {number} y Tile coordinate y.
|
||||
* @return {boolean} Contains coordinate.
|
||||
*/
|
||||
containsXY(x, y) {
|
||||
return this.minX <= x && x <= this.maxX && this.minY <= y && y <= this.maxY;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {module:ol/TileRange} tileRange Tile range.
|
||||
* @return {boolean} Equals.
|
||||
*/
|
||||
equals(tileRange) {
|
||||
return this.minX == tileRange.minX && this.minY == tileRange.minY &&
|
||||
this.maxX == tileRange.maxX && this.maxY == tileRange.maxY;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {module:ol/TileRange} tileRange Tile range.
|
||||
*/
|
||||
extend(tileRange) {
|
||||
if (tileRange.minX < this.minX) {
|
||||
this.minX = tileRange.minX;
|
||||
}
|
||||
if (tileRange.maxX > this.maxX) {
|
||||
this.maxX = tileRange.maxX;
|
||||
}
|
||||
if (tileRange.minY < this.minY) {
|
||||
this.minY = tileRange.minY;
|
||||
}
|
||||
if (tileRange.maxY > this.maxY) {
|
||||
this.maxY = tileRange.maxY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {number} Height.
|
||||
*/
|
||||
getHeight() {
|
||||
return this.maxY - this.minY + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {module:ol/size~Size} Size.
|
||||
*/
|
||||
getSize() {
|
||||
return [this.getWidth(), this.getHeight()];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {number} Width.
|
||||
*/
|
||||
getWidth() {
|
||||
return this.maxX - this.minX + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {module:ol/TileRange} tileRange Tile range.
|
||||
* @return {boolean} Intersects.
|
||||
*/
|
||||
intersects(tileRange) {
|
||||
return this.minX <= tileRange.maxX &&
|
||||
this.maxX >= tileRange.minX &&
|
||||
this.minY <= tileRange.maxY &&
|
||||
this.maxY >= tileRange.minY;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@@ -58,96 +145,4 @@ export function createOrUpdate(minX, maxX, minY, maxY, tileRange) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {module:ol/tilecoord~TileCoord} tileCoord Tile coordinate.
|
||||
* @return {boolean} Contains tile coordinate.
|
||||
*/
|
||||
TileRange.prototype.contains = function(tileCoord) {
|
||||
return this.containsXY(tileCoord[1], tileCoord[2]);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {module:ol/TileRange} tileRange Tile range.
|
||||
* @return {boolean} Contains.
|
||||
*/
|
||||
TileRange.prototype.containsTileRange = function(tileRange) {
|
||||
return this.minX <= tileRange.minX && tileRange.maxX <= this.maxX &&
|
||||
this.minY <= tileRange.minY && tileRange.maxY <= this.maxY;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} x Tile coordinate x.
|
||||
* @param {number} y Tile coordinate y.
|
||||
* @return {boolean} Contains coordinate.
|
||||
*/
|
||||
TileRange.prototype.containsXY = function(x, y) {
|
||||
return this.minX <= x && x <= this.maxX && this.minY <= y && y <= this.maxY;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {module:ol/TileRange} tileRange Tile range.
|
||||
* @return {boolean} Equals.
|
||||
*/
|
||||
TileRange.prototype.equals = function(tileRange) {
|
||||
return this.minX == tileRange.minX && this.minY == tileRange.minY &&
|
||||
this.maxX == tileRange.maxX && this.maxY == tileRange.maxY;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {module:ol/TileRange} tileRange Tile range.
|
||||
*/
|
||||
TileRange.prototype.extend = function(tileRange) {
|
||||
if (tileRange.minX < this.minX) {
|
||||
this.minX = tileRange.minX;
|
||||
}
|
||||
if (tileRange.maxX > this.maxX) {
|
||||
this.maxX = tileRange.maxX;
|
||||
}
|
||||
if (tileRange.minY < this.minY) {
|
||||
this.minY = tileRange.minY;
|
||||
}
|
||||
if (tileRange.maxY > this.maxY) {
|
||||
this.maxY = tileRange.maxY;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} Height.
|
||||
*/
|
||||
TileRange.prototype.getHeight = function() {
|
||||
return this.maxY - this.minY + 1;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {module:ol/size~Size} Size.
|
||||
*/
|
||||
TileRange.prototype.getSize = function() {
|
||||
return [this.getWidth(), this.getHeight()];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} Width.
|
||||
*/
|
||||
TileRange.prototype.getWidth = function() {
|
||||
return this.maxX - this.minX + 1;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {module:ol/TileRange} tileRange Tile range.
|
||||
* @return {boolean} Intersects.
|
||||
*/
|
||||
TileRange.prototype.intersects = function(tileRange) {
|
||||
return this.minX <= tileRange.maxX &&
|
||||
this.maxX >= tileRange.minX &&
|
||||
this.minY <= tileRange.maxY &&
|
||||
this.maxY >= tileRange.minY;
|
||||
};
|
||||
export default TileRange;
|
||||
|
||||
@@ -43,286 +43,295 @@ import {UNDEFINED} from './functions.js';
|
||||
* Function to call when a source tile's state changes.
|
||||
* @param {number} zoom Integer zoom to render the tile for.
|
||||
*/
|
||||
const VectorImageTile = function(tileCoord, state, sourceRevision, format,
|
||||
tileLoadFunction, urlTileCoord, tileUrlFunction, sourceTileGrid, tileGrid,
|
||||
sourceTiles, pixelRatio, projection, tileClass, handleTileChange, zoom) {
|
||||
class VectorImageTile {
|
||||
constructor(
|
||||
tileCoord,
|
||||
state,
|
||||
sourceRevision,
|
||||
format,
|
||||
tileLoadFunction,
|
||||
urlTileCoord,
|
||||
tileUrlFunction,
|
||||
sourceTileGrid,
|
||||
tileGrid,
|
||||
sourceTiles,
|
||||
pixelRatio,
|
||||
projection,
|
||||
tileClass,
|
||||
handleTileChange,
|
||||
zoom
|
||||
) {
|
||||
|
||||
Tile.call(this, tileCoord, state, {transition: 0});
|
||||
Tile.call(this, tileCoord, state, {transition: 0});
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {!Object.<string, CanvasRenderingContext2D>}
|
||||
*/
|
||||
this.context_ = {};
|
||||
/**
|
||||
* @private
|
||||
* @type {!Object.<string, CanvasRenderingContext2D>}
|
||||
*/
|
||||
this.context_ = {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/featureloader~FeatureLoader}
|
||||
*/
|
||||
this.loader_;
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/featureloader~FeatureLoader}
|
||||
*/
|
||||
this.loader_;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {!Object.<string, module:ol/VectorImageTile~ReplayState>}
|
||||
*/
|
||||
this.replayState_ = {};
|
||||
/**
|
||||
* @private
|
||||
* @type {!Object.<string, module:ol/VectorImageTile~ReplayState>}
|
||||
*/
|
||||
this.replayState_ = {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Object.<string, module:ol/VectorTile>}
|
||||
*/
|
||||
this.sourceTiles_ = sourceTiles;
|
||||
/**
|
||||
* @private
|
||||
* @type {Object.<string, module:ol/VectorTile>}
|
||||
*/
|
||||
this.sourceTiles_ = sourceTiles;
|
||||
|
||||
/**
|
||||
* Keys of source tiles used by this tile. Use with {@link #getTile}.
|
||||
* @type {Array.<string>}
|
||||
*/
|
||||
this.tileKeys = [];
|
||||
/**
|
||||
* Keys of source tiles used by this tile. Use with {@link #getTile}.
|
||||
* @type {Array.<string>}
|
||||
*/
|
||||
this.tileKeys = [];
|
||||
|
||||
/**
|
||||
* @type {module:ol/extent~Extent}
|
||||
*/
|
||||
this.extent = null;
|
||||
/**
|
||||
* @type {module:ol/extent~Extent}
|
||||
*/
|
||||
this.extent = null;
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.sourceRevision_ = sourceRevision;
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.sourceRevision_ = sourceRevision;
|
||||
|
||||
/**
|
||||
* @type {module:ol/tilecoord~TileCoord}
|
||||
*/
|
||||
this.wrappedTileCoord = urlTileCoord;
|
||||
/**
|
||||
* @type {module:ol/tilecoord~TileCoord}
|
||||
*/
|
||||
this.wrappedTileCoord = urlTileCoord;
|
||||
|
||||
/**
|
||||
* @type {Array.<module:ol/events~EventsKey>}
|
||||
*/
|
||||
this.loadListenerKeys_ = [];
|
||||
/**
|
||||
* @type {Array.<module:ol/events~EventsKey>}
|
||||
*/
|
||||
this.loadListenerKeys_ = [];
|
||||
|
||||
/**
|
||||
* @type {Array.<module:ol/events~EventsKey>}
|
||||
*/
|
||||
this.sourceTileListenerKeys_ = [];
|
||||
/**
|
||||
* @type {Array.<module:ol/events~EventsKey>}
|
||||
*/
|
||||
this.sourceTileListenerKeys_ = [];
|
||||
|
||||
if (urlTileCoord) {
|
||||
const extent = this.extent = tileGrid.getTileCoordExtent(urlTileCoord);
|
||||
const resolution = tileGrid.getResolution(zoom);
|
||||
const sourceZ = sourceTileGrid.getZForResolution(resolution);
|
||||
const useLoadedOnly = zoom != tileCoord[0];
|
||||
let loadCount = 0;
|
||||
sourceTileGrid.forEachTileCoord(extent, sourceZ, function(sourceTileCoord) {
|
||||
let sharedExtent = getIntersection(extent,
|
||||
sourceTileGrid.getTileCoordExtent(sourceTileCoord));
|
||||
const sourceExtent = sourceTileGrid.getExtent();
|
||||
if (sourceExtent) {
|
||||
sharedExtent = getIntersection(sharedExtent, sourceExtent, sharedExtent);
|
||||
}
|
||||
if (getWidth(sharedExtent) / resolution >= 0.5 &&
|
||||
getHeight(sharedExtent) / resolution >= 0.5) {
|
||||
// only include source tile if overlap is at least 1 pixel
|
||||
++loadCount;
|
||||
const sourceTileKey = sourceTileCoord.toString();
|
||||
let sourceTile = sourceTiles[sourceTileKey];
|
||||
if (!sourceTile && !useLoadedOnly) {
|
||||
const tileUrl = tileUrlFunction(sourceTileCoord, pixelRatio, projection);
|
||||
sourceTile = sourceTiles[sourceTileKey] = new tileClass(sourceTileCoord,
|
||||
tileUrl == undefined ? TileState.EMPTY : TileState.IDLE,
|
||||
tileUrl == undefined ? '' : tileUrl,
|
||||
format, tileLoadFunction);
|
||||
this.sourceTileListenerKeys_.push(
|
||||
listen(sourceTile, EventType.CHANGE, handleTileChange));
|
||||
if (urlTileCoord) {
|
||||
const extent = this.extent = tileGrid.getTileCoordExtent(urlTileCoord);
|
||||
const resolution = tileGrid.getResolution(zoom);
|
||||
const sourceZ = sourceTileGrid.getZForResolution(resolution);
|
||||
const useLoadedOnly = zoom != tileCoord[0];
|
||||
let loadCount = 0;
|
||||
sourceTileGrid.forEachTileCoord(extent, sourceZ, function(sourceTileCoord) {
|
||||
let sharedExtent = getIntersection(extent,
|
||||
sourceTileGrid.getTileCoordExtent(sourceTileCoord));
|
||||
const sourceExtent = sourceTileGrid.getExtent();
|
||||
if (sourceExtent) {
|
||||
sharedExtent = getIntersection(sharedExtent, sourceExtent, sharedExtent);
|
||||
}
|
||||
if (sourceTile && (!useLoadedOnly || sourceTile.getState() == TileState.LOADED)) {
|
||||
sourceTile.consumers++;
|
||||
this.tileKeys.push(sourceTileKey);
|
||||
if (getWidth(sharedExtent) / resolution >= 0.5 &&
|
||||
getHeight(sharedExtent) / resolution >= 0.5) {
|
||||
// only include source tile if overlap is at least 1 pixel
|
||||
++loadCount;
|
||||
const sourceTileKey = sourceTileCoord.toString();
|
||||
let sourceTile = sourceTiles[sourceTileKey];
|
||||
if (!sourceTile && !useLoadedOnly) {
|
||||
const tileUrl = tileUrlFunction(sourceTileCoord, pixelRatio, projection);
|
||||
sourceTile = sourceTiles[sourceTileKey] = new tileClass(sourceTileCoord,
|
||||
tileUrl == undefined ? TileState.EMPTY : TileState.IDLE,
|
||||
tileUrl == undefined ? '' : tileUrl,
|
||||
format, tileLoadFunction);
|
||||
this.sourceTileListenerKeys_.push(
|
||||
listen(sourceTile, EventType.CHANGE, handleTileChange));
|
||||
}
|
||||
if (sourceTile && (!useLoadedOnly || sourceTile.getState() == TileState.LOADED)) {
|
||||
sourceTile.consumers++;
|
||||
this.tileKeys.push(sourceTileKey);
|
||||
}
|
||||
}
|
||||
}.bind(this));
|
||||
|
||||
if (useLoadedOnly && loadCount == this.tileKeys.length) {
|
||||
this.finishLoading_();
|
||||
}
|
||||
|
||||
if (zoom <= tileCoord[0] && this.state != TileState.LOADED) {
|
||||
while (zoom > tileGrid.getMinZoom()) {
|
||||
const tile = new VectorImageTile(tileCoord, state, sourceRevision,
|
||||
format, tileLoadFunction, urlTileCoord, tileUrlFunction,
|
||||
sourceTileGrid, tileGrid, sourceTiles, pixelRatio, projection,
|
||||
tileClass, UNDEFINED, --zoom);
|
||||
if (tile.state == TileState.LOADED) {
|
||||
this.interimTile = tile;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}.bind(this));
|
||||
|
||||
if (useLoadedOnly && loadCount == this.tileKeys.length) {
|
||||
this.finishLoading_();
|
||||
}
|
||||
|
||||
if (zoom <= tileCoord[0] && this.state != TileState.LOADED) {
|
||||
while (zoom > tileGrid.getMinZoom()) {
|
||||
const tile = new VectorImageTile(tileCoord, state, sourceRevision,
|
||||
format, tileLoadFunction, urlTileCoord, tileUrlFunction,
|
||||
sourceTileGrid, tileGrid, sourceTiles, pixelRatio, projection,
|
||||
tileClass, UNDEFINED, --zoom);
|
||||
if (tile.state == TileState.LOADED) {
|
||||
this.interimTile = tile;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
disposeInternal() {
|
||||
this.state = TileState.ABORT;
|
||||
this.changed();
|
||||
if (this.interimTile) {
|
||||
this.interimTile.dispose();
|
||||
}
|
||||
|
||||
for (let i = 0, ii = this.tileKeys.length; i < ii; ++i) {
|
||||
const sourceTileKey = this.tileKeys[i];
|
||||
const sourceTile = this.getTile(sourceTileKey);
|
||||
sourceTile.consumers--;
|
||||
if (sourceTile.consumers == 0) {
|
||||
delete this.sourceTiles_[sourceTileKey];
|
||||
sourceTile.dispose();
|
||||
}
|
||||
}
|
||||
this.tileKeys.length = 0;
|
||||
this.sourceTiles_ = null;
|
||||
this.loadListenerKeys_.forEach(unlistenByKey);
|
||||
this.loadListenerKeys_.length = 0;
|
||||
this.sourceTileListenerKeys_.forEach(unlistenByKey);
|
||||
this.sourceTileListenerKeys_.length = 0;
|
||||
Tile.prototype.disposeInternal.call(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {module:ol/layer/Layer} layer Layer.
|
||||
* @return {CanvasRenderingContext2D} The rendering context.
|
||||
*/
|
||||
getContext(layer) {
|
||||
const key = getUid(layer).toString();
|
||||
if (!(key in this.context_)) {
|
||||
this.context_[key] = createCanvasContext2D();
|
||||
}
|
||||
return this.context_[key];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Canvas for this tile.
|
||||
* @param {module:ol/layer/Layer} layer Layer.
|
||||
* @return {HTMLCanvasElement} Canvas.
|
||||
*/
|
||||
getImage(layer) {
|
||||
return this.getReplayState(layer).renderedTileRevision == -1 ?
|
||||
null : this.getContext(layer).canvas;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {module:ol/layer/Layer} layer Layer.
|
||||
* @return {module:ol/VectorImageTile~ReplayState} The replay state.
|
||||
*/
|
||||
getReplayState(layer) {
|
||||
const key = getUid(layer).toString();
|
||||
if (!(key in this.replayState_)) {
|
||||
this.replayState_[key] = {
|
||||
dirty: false,
|
||||
renderedRenderOrder: null,
|
||||
renderedRevision: -1,
|
||||
renderedTileRevision: -1
|
||||
};
|
||||
}
|
||||
return this.replayState_[key];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
getKey() {
|
||||
return this.tileKeys.join('/') + '-' + this.sourceRevision_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} tileKey Key (tileCoord) of the source tile.
|
||||
* @return {module:ol/VectorTile} Source tile.
|
||||
*/
|
||||
getTile(tileKey) {
|
||||
return this.sourceTiles_[tileKey];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
load() {
|
||||
// Source tiles with LOADED state - we just count them because once they are
|
||||
// loaded, we're no longer listening to state changes.
|
||||
let leftToLoad = 0;
|
||||
// Source tiles with ERROR state - we track them because they can still have
|
||||
// an ERROR state after another load attempt.
|
||||
const errorSourceTiles = {};
|
||||
|
||||
if (this.state == TileState.IDLE) {
|
||||
this.setState(TileState.LOADING);
|
||||
}
|
||||
if (this.state == TileState.LOADING) {
|
||||
this.tileKeys.forEach(function(sourceTileKey) {
|
||||
const sourceTile = this.getTile(sourceTileKey);
|
||||
if (sourceTile.state == TileState.IDLE) {
|
||||
sourceTile.setLoader(this.loader_);
|
||||
sourceTile.load();
|
||||
}
|
||||
if (sourceTile.state == TileState.LOADING) {
|
||||
const key = listen(sourceTile, EventType.CHANGE, function(e) {
|
||||
const state = sourceTile.getState();
|
||||
if (state == TileState.LOADED ||
|
||||
state == TileState.ERROR) {
|
||||
const uid = getUid(sourceTile);
|
||||
if (state == TileState.ERROR) {
|
||||
errorSourceTiles[uid] = true;
|
||||
} else {
|
||||
--leftToLoad;
|
||||
delete errorSourceTiles[uid];
|
||||
}
|
||||
if (leftToLoad - Object.keys(errorSourceTiles).length == 0) {
|
||||
this.finishLoading_();
|
||||
}
|
||||
}
|
||||
}.bind(this));
|
||||
this.loadListenerKeys_.push(key);
|
||||
++leftToLoad;
|
||||
}
|
||||
}.bind(this));
|
||||
}
|
||||
if (leftToLoad - Object.keys(errorSourceTiles).length == 0) {
|
||||
setTimeout(this.finishLoading_.bind(this), 0);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
finishLoading_() {
|
||||
let loaded = this.tileKeys.length;
|
||||
let empty = 0;
|
||||
for (let i = loaded - 1; i >= 0; --i) {
|
||||
const state = this.getTile(this.tileKeys[i]).getState();
|
||||
if (state != TileState.LOADED) {
|
||||
--loaded;
|
||||
}
|
||||
if (state == TileState.EMPTY) {
|
||||
++empty;
|
||||
}
|
||||
}
|
||||
if (loaded == this.tileKeys.length) {
|
||||
this.loadListenerKeys_.forEach(unlistenByKey);
|
||||
this.loadListenerKeys_.length = 0;
|
||||
this.setState(TileState.LOADED);
|
||||
} else {
|
||||
this.setState(empty == this.tileKeys.length ? TileState.EMPTY : TileState.ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inherits(VectorImageTile, Tile);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
VectorImageTile.prototype.disposeInternal = function() {
|
||||
this.state = TileState.ABORT;
|
||||
this.changed();
|
||||
if (this.interimTile) {
|
||||
this.interimTile.dispose();
|
||||
}
|
||||
|
||||
for (let i = 0, ii = this.tileKeys.length; i < ii; ++i) {
|
||||
const sourceTileKey = this.tileKeys[i];
|
||||
const sourceTile = this.getTile(sourceTileKey);
|
||||
sourceTile.consumers--;
|
||||
if (sourceTile.consumers == 0) {
|
||||
delete this.sourceTiles_[sourceTileKey];
|
||||
sourceTile.dispose();
|
||||
}
|
||||
}
|
||||
this.tileKeys.length = 0;
|
||||
this.sourceTiles_ = null;
|
||||
this.loadListenerKeys_.forEach(unlistenByKey);
|
||||
this.loadListenerKeys_.length = 0;
|
||||
this.sourceTileListenerKeys_.forEach(unlistenByKey);
|
||||
this.sourceTileListenerKeys_.length = 0;
|
||||
Tile.prototype.disposeInternal.call(this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {module:ol/layer/Layer} layer Layer.
|
||||
* @return {CanvasRenderingContext2D} The rendering context.
|
||||
*/
|
||||
VectorImageTile.prototype.getContext = function(layer) {
|
||||
const key = getUid(layer).toString();
|
||||
if (!(key in this.context_)) {
|
||||
this.context_[key] = createCanvasContext2D();
|
||||
}
|
||||
return this.context_[key];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the Canvas for this tile.
|
||||
* @param {module:ol/layer/Layer} layer Layer.
|
||||
* @return {HTMLCanvasElement} Canvas.
|
||||
*/
|
||||
VectorImageTile.prototype.getImage = function(layer) {
|
||||
return this.getReplayState(layer).renderedTileRevision == -1 ?
|
||||
null : this.getContext(layer).canvas;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {module:ol/layer/Layer} layer Layer.
|
||||
* @return {module:ol/VectorImageTile~ReplayState} The replay state.
|
||||
*/
|
||||
VectorImageTile.prototype.getReplayState = function(layer) {
|
||||
const key = getUid(layer).toString();
|
||||
if (!(key in this.replayState_)) {
|
||||
this.replayState_[key] = {
|
||||
dirty: false,
|
||||
renderedRenderOrder: null,
|
||||
renderedRevision: -1,
|
||||
renderedTileRevision: -1
|
||||
};
|
||||
}
|
||||
return this.replayState_[key];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
VectorImageTile.prototype.getKey = function() {
|
||||
return this.tileKeys.join('/') + '-' + this.sourceRevision_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} tileKey Key (tileCoord) of the source tile.
|
||||
* @return {module:ol/VectorTile} Source tile.
|
||||
*/
|
||||
VectorImageTile.prototype.getTile = function(tileKey) {
|
||||
return this.sourceTiles_[tileKey];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
VectorImageTile.prototype.load = function() {
|
||||
// Source tiles with LOADED state - we just count them because once they are
|
||||
// loaded, we're no longer listening to state changes.
|
||||
let leftToLoad = 0;
|
||||
// Source tiles with ERROR state - we track them because they can still have
|
||||
// an ERROR state after another load attempt.
|
||||
const errorSourceTiles = {};
|
||||
|
||||
if (this.state == TileState.IDLE) {
|
||||
this.setState(TileState.LOADING);
|
||||
}
|
||||
if (this.state == TileState.LOADING) {
|
||||
this.tileKeys.forEach(function(sourceTileKey) {
|
||||
const sourceTile = this.getTile(sourceTileKey);
|
||||
if (sourceTile.state == TileState.IDLE) {
|
||||
sourceTile.setLoader(this.loader_);
|
||||
sourceTile.load();
|
||||
}
|
||||
if (sourceTile.state == TileState.LOADING) {
|
||||
const key = listen(sourceTile, EventType.CHANGE, function(e) {
|
||||
const state = sourceTile.getState();
|
||||
if (state == TileState.LOADED ||
|
||||
state == TileState.ERROR) {
|
||||
const uid = getUid(sourceTile);
|
||||
if (state == TileState.ERROR) {
|
||||
errorSourceTiles[uid] = true;
|
||||
} else {
|
||||
--leftToLoad;
|
||||
delete errorSourceTiles[uid];
|
||||
}
|
||||
if (leftToLoad - Object.keys(errorSourceTiles).length == 0) {
|
||||
this.finishLoading_();
|
||||
}
|
||||
}
|
||||
}.bind(this));
|
||||
this.loadListenerKeys_.push(key);
|
||||
++leftToLoad;
|
||||
}
|
||||
}.bind(this));
|
||||
}
|
||||
if (leftToLoad - Object.keys(errorSourceTiles).length == 0) {
|
||||
setTimeout(this.finishLoading_.bind(this), 0);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
VectorImageTile.prototype.finishLoading_ = function() {
|
||||
let loaded = this.tileKeys.length;
|
||||
let empty = 0;
|
||||
for (let i = loaded - 1; i >= 0; --i) {
|
||||
const state = this.getTile(this.tileKeys[i]).getState();
|
||||
if (state != TileState.LOADED) {
|
||||
--loaded;
|
||||
}
|
||||
if (state == TileState.EMPTY) {
|
||||
++empty;
|
||||
}
|
||||
}
|
||||
if (loaded == this.tileKeys.length) {
|
||||
this.loadListenerKeys_.forEach(unlistenByKey);
|
||||
this.loadListenerKeys_.length = 0;
|
||||
this.setState(TileState.LOADED);
|
||||
} else {
|
||||
this.setState(empty == this.tileKeys.length ? TileState.EMPTY : TileState.ERROR);
|
||||
}
|
||||
};
|
||||
|
||||
export default VectorImageTile;
|
||||
|
||||
/**
|
||||
|
||||
@@ -21,65 +21,218 @@ import TileState from './TileState.js';
|
||||
* @param {module:ol/Tile~LoadFunction} tileLoadFunction Tile load function.
|
||||
* @param {module:ol/Tile~Options=} opt_options Tile options.
|
||||
*/
|
||||
const VectorTile = function(tileCoord, state, src, format, tileLoadFunction, opt_options) {
|
||||
class VectorTile {
|
||||
constructor(tileCoord, state, src, format, tileLoadFunction, opt_options) {
|
||||
|
||||
Tile.call(this, tileCoord, state, opt_options);
|
||||
Tile.call(this, tileCoord, state, opt_options);
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.consumers = 0;
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.consumers = 0;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/extent~Extent}
|
||||
*/
|
||||
this.extent_ = null;
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/extent~Extent}
|
||||
*/
|
||||
this.extent_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/format/Feature}
|
||||
*/
|
||||
this.format_ = format;
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/format/Feature}
|
||||
*/
|
||||
this.format_ = format;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<module:ol/Feature>}
|
||||
*/
|
||||
this.features_ = null;
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<module:ol/Feature>}
|
||||
*/
|
||||
this.features_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/featureloader~FeatureLoader}
|
||||
*/
|
||||
this.loader_;
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/featureloader~FeatureLoader}
|
||||
*/
|
||||
this.loader_;
|
||||
|
||||
/**
|
||||
* Data projection
|
||||
* @private
|
||||
* @type {module:ol/proj/Projection}
|
||||
*/
|
||||
this.projection_ = null;
|
||||
/**
|
||||
* Data projection
|
||||
* @private
|
||||
* @type {module:ol/proj/Projection}
|
||||
*/
|
||||
this.projection_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Object.<string, module:ol/render/ReplayGroup>}
|
||||
*/
|
||||
this.replayGroups_ = {};
|
||||
/**
|
||||
* @private
|
||||
* @type {Object.<string, module:ol/render/ReplayGroup>}
|
||||
*/
|
||||
this.replayGroups_ = {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/Tile~LoadFunction}
|
||||
*/
|
||||
this.tileLoadFunction_ = tileLoadFunction;
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/Tile~LoadFunction}
|
||||
*/
|
||||
this.tileLoadFunction_ = tileLoadFunction;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {string}
|
||||
*/
|
||||
this.url_ = src;
|
||||
/**
|
||||
* @private
|
||||
* @type {string}
|
||||
*/
|
||||
this.url_ = src;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
disposeInternal() {
|
||||
this.features_ = null;
|
||||
this.replayGroups_ = {};
|
||||
this.state = TileState.ABORT;
|
||||
this.changed();
|
||||
Tile.prototype.disposeInternal.call(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the extent of the vector tile.
|
||||
* @return {module:ol/extent~Extent} The extent.
|
||||
* @api
|
||||
*/
|
||||
getExtent() {
|
||||
return this.extent_ || DEFAULT_EXTENT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the feature format assigned for reading this tile's features.
|
||||
* @return {module:ol/format/Feature} Feature format.
|
||||
* @api
|
||||
*/
|
||||
getFormat() {
|
||||
return this.format_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the features for this tile. Geometries will be in the projection returned
|
||||
* by {@link module:ol/VectorTile~VectorTile#getProjection}.
|
||||
* @return {Array.<module:ol/Feature|module:ol/render/Feature>} Features.
|
||||
* @api
|
||||
*/
|
||||
getFeatures() {
|
||||
return this.features_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
getKey() {
|
||||
return this.url_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the feature projection of features returned by
|
||||
* {@link module:ol/VectorTile~VectorTile#getFeatures}.
|
||||
* @return {module:ol/proj/Projection} Feature projection.
|
||||
* @api
|
||||
*/
|
||||
getProjection() {
|
||||
return this.projection_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {module:ol/layer/Layer} layer Layer.
|
||||
* @param {string} key Key.
|
||||
* @return {module:ol/render/ReplayGroup} Replay group.
|
||||
*/
|
||||
getReplayGroup(layer, key) {
|
||||
return this.replayGroups_[getUid(layer) + ',' + key];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
load() {
|
||||
if (this.state == TileState.IDLE) {
|
||||
this.setState(TileState.LOADING);
|
||||
this.tileLoadFunction_(this, this.url_);
|
||||
this.loader_(null, NaN, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for successful tile load.
|
||||
* @param {Array.<module:ol/Feature>} features The loaded features.
|
||||
* @param {module:ol/proj/Projection} dataProjection Data projection.
|
||||
* @param {module:ol/extent~Extent} extent Extent.
|
||||
*/
|
||||
onLoad(features, dataProjection, extent) {
|
||||
this.setProjection(dataProjection);
|
||||
this.setFeatures(features);
|
||||
this.setExtent(extent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for tile load errors.
|
||||
*/
|
||||
onError() {
|
||||
this.setState(TileState.ERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for use in an {@link module:ol/source/VectorTile~VectorTile}'s
|
||||
* `tileLoadFunction`. Sets the extent of the vector tile. This is only required
|
||||
* for tiles in projections with `tile-pixels` as units. The extent should be
|
||||
* set to `[0, 0, tilePixelSize, tilePixelSize]`, where `tilePixelSize` is
|
||||
* calculated by multiplying the tile size with the tile pixel ratio. For
|
||||
* sources using {@link module:ol/format/MVT~MVT} as feature format, the
|
||||
* {@link module:ol/format/MVT~MVT#getLastExtent} method will return the correct
|
||||
* extent. The default is `[0, 0, 4096, 4096]`.
|
||||
* @param {module:ol/extent~Extent} extent The extent.
|
||||
* @api
|
||||
*/
|
||||
setExtent(extent) {
|
||||
this.extent_ = extent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for use in an {@link module:ol/source/VectorTile~VectorTile}'s `tileLoadFunction`.
|
||||
* Sets the features for the tile.
|
||||
* @param {Array.<module:ol/Feature>} features Features.
|
||||
* @api
|
||||
*/
|
||||
setFeatures(features) {
|
||||
this.features_ = features;
|
||||
this.setState(TileState.LOADED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for use in an {@link module:ol/source/VectorTile~VectorTile}'s `tileLoadFunction`.
|
||||
* Sets the projection of the features that were added with
|
||||
* {@link module:ol/VectorTile~VectorTile#setFeatures}.
|
||||
* @param {module:ol/proj/Projection} projection Feature projection.
|
||||
* @api
|
||||
*/
|
||||
setProjection(projection) {
|
||||
this.projection_ = projection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {module:ol/layer/Layer} layer Layer.
|
||||
* @param {string} key Key.
|
||||
* @param {module:ol/render/ReplayGroup} replayGroup Replay group.
|
||||
*/
|
||||
setReplayGroup(layer, key, replayGroup) {
|
||||
this.replayGroups_[getUid(layer) + ',' + key] = replayGroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the feature loader for reading this tile's features.
|
||||
* @param {module:ol/featureloader~FeatureLoader} loader Feature loader.
|
||||
* @api
|
||||
*/
|
||||
setLoader(loader) {
|
||||
this.loader_ = loader;
|
||||
}
|
||||
}
|
||||
|
||||
inherits(VectorTile, Tile);
|
||||
|
||||
@@ -90,169 +243,4 @@ inherits(VectorTile, Tile);
|
||||
const DEFAULT_EXTENT = [0, 0, 4096, 4096];
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
VectorTile.prototype.disposeInternal = function() {
|
||||
this.features_ = null;
|
||||
this.replayGroups_ = {};
|
||||
this.state = TileState.ABORT;
|
||||
this.changed();
|
||||
Tile.prototype.disposeInternal.call(this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets the extent of the vector tile.
|
||||
* @return {module:ol/extent~Extent} The extent.
|
||||
* @api
|
||||
*/
|
||||
VectorTile.prototype.getExtent = function() {
|
||||
return this.extent_ || DEFAULT_EXTENT;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the feature format assigned for reading this tile's features.
|
||||
* @return {module:ol/format/Feature} Feature format.
|
||||
* @api
|
||||
*/
|
||||
VectorTile.prototype.getFormat = function() {
|
||||
return this.format_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the features for this tile. Geometries will be in the projection returned
|
||||
* by {@link module:ol/VectorTile~VectorTile#getProjection}.
|
||||
* @return {Array.<module:ol/Feature|module:ol/render/Feature>} Features.
|
||||
* @api
|
||||
*/
|
||||
VectorTile.prototype.getFeatures = function() {
|
||||
return this.features_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
VectorTile.prototype.getKey = function() {
|
||||
return this.url_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the feature projection of features returned by
|
||||
* {@link module:ol/VectorTile~VectorTile#getFeatures}.
|
||||
* @return {module:ol/proj/Projection} Feature projection.
|
||||
* @api
|
||||
*/
|
||||
VectorTile.prototype.getProjection = function() {
|
||||
return this.projection_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {module:ol/layer/Layer} layer Layer.
|
||||
* @param {string} key Key.
|
||||
* @return {module:ol/render/ReplayGroup} Replay group.
|
||||
*/
|
||||
VectorTile.prototype.getReplayGroup = function(layer, key) {
|
||||
return this.replayGroups_[getUid(layer) + ',' + key];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
VectorTile.prototype.load = function() {
|
||||
if (this.state == TileState.IDLE) {
|
||||
this.setState(TileState.LOADING);
|
||||
this.tileLoadFunction_(this, this.url_);
|
||||
this.loader_(null, NaN, null);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handler for successful tile load.
|
||||
* @param {Array.<module:ol/Feature>} features The loaded features.
|
||||
* @param {module:ol/proj/Projection} dataProjection Data projection.
|
||||
* @param {module:ol/extent~Extent} extent Extent.
|
||||
*/
|
||||
VectorTile.prototype.onLoad = function(features, dataProjection, extent) {
|
||||
this.setProjection(dataProjection);
|
||||
this.setFeatures(features);
|
||||
this.setExtent(extent);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handler for tile load errors.
|
||||
*/
|
||||
VectorTile.prototype.onError = function() {
|
||||
this.setState(TileState.ERROR);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Function for use in an {@link module:ol/source/VectorTile~VectorTile}'s
|
||||
* `tileLoadFunction`. Sets the extent of the vector tile. This is only required
|
||||
* for tiles in projections with `tile-pixels` as units. The extent should be
|
||||
* set to `[0, 0, tilePixelSize, tilePixelSize]`, where `tilePixelSize` is
|
||||
* calculated by multiplying the tile size with the tile pixel ratio. For
|
||||
* sources using {@link module:ol/format/MVT~MVT} as feature format, the
|
||||
* {@link module:ol/format/MVT~MVT#getLastExtent} method will return the correct
|
||||
* extent. The default is `[0, 0, 4096, 4096]`.
|
||||
* @param {module:ol/extent~Extent} extent The extent.
|
||||
* @api
|
||||
*/
|
||||
VectorTile.prototype.setExtent = function(extent) {
|
||||
this.extent_ = extent;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Function for use in an {@link module:ol/source/VectorTile~VectorTile}'s `tileLoadFunction`.
|
||||
* Sets the features for the tile.
|
||||
* @param {Array.<module:ol/Feature>} features Features.
|
||||
* @api
|
||||
*/
|
||||
VectorTile.prototype.setFeatures = function(features) {
|
||||
this.features_ = features;
|
||||
this.setState(TileState.LOADED);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Function for use in an {@link module:ol/source/VectorTile~VectorTile}'s `tileLoadFunction`.
|
||||
* Sets the projection of the features that were added with
|
||||
* {@link module:ol/VectorTile~VectorTile#setFeatures}.
|
||||
* @param {module:ol/proj/Projection} projection Feature projection.
|
||||
* @api
|
||||
*/
|
||||
VectorTile.prototype.setProjection = function(projection) {
|
||||
this.projection_ = projection;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {module:ol/layer/Layer} layer Layer.
|
||||
* @param {string} key Key.
|
||||
* @param {module:ol/render/ReplayGroup} replayGroup Replay group.
|
||||
*/
|
||||
VectorTile.prototype.setReplayGroup = function(layer, key, replayGroup) {
|
||||
this.replayGroups_[getUid(layer) + ',' + key] = replayGroup;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the feature loader for reading this tile's features.
|
||||
* @param {module:ol/featureloader~FeatureLoader} loader Feature loader.
|
||||
* @api
|
||||
*/
|
||||
VectorTile.prototype.setLoader = function(loader) {
|
||||
this.loader_ = loader;
|
||||
};
|
||||
|
||||
export default VectorTile;
|
||||
|
||||
1804
src/ol/View.js
1804
src/ol/View.js
File diff suppressed because it is too large
Load Diff
@@ -66,29 +66,31 @@ import WebGLVectorLayerRenderer from './renderer/webgl/VectorLayer.js';
|
||||
* @fires module:ol/render/Event~RenderEvent#precompose
|
||||
* @api
|
||||
*/
|
||||
const WebGLMap = function(options) {
|
||||
options = assign({}, options);
|
||||
if (!options.controls) {
|
||||
options.controls = defaultControls();
|
||||
}
|
||||
if (!options.interactions) {
|
||||
options.interactions = defaultInteractions();
|
||||
class WebGLMap {
|
||||
constructor(options) {
|
||||
options = assign({}, options);
|
||||
if (!options.controls) {
|
||||
options.controls = defaultControls();
|
||||
}
|
||||
if (!options.interactions) {
|
||||
options.interactions = defaultInteractions();
|
||||
}
|
||||
|
||||
PluggableMap.call(this, options);
|
||||
}
|
||||
|
||||
PluggableMap.call(this, options);
|
||||
};
|
||||
createRenderer() {
|
||||
const renderer = new WebGLMapRenderer(this);
|
||||
renderer.registerLayerRenderers([
|
||||
WebGLImageLayerRenderer,
|
||||
WebGLTileLayerRenderer,
|
||||
WebGLVectorLayerRenderer
|
||||
]);
|
||||
return renderer;
|
||||
}
|
||||
}
|
||||
|
||||
inherits(WebGLMap, PluggableMap);
|
||||
|
||||
|
||||
WebGLMap.prototype.createRenderer = function() {
|
||||
const renderer = new WebGLMapRenderer(this);
|
||||
renderer.registerLayerRenderers([
|
||||
WebGLImageLayerRenderer,
|
||||
WebGLTileLayerRenderer,
|
||||
WebGLVectorLayerRenderer
|
||||
]);
|
||||
return renderer;
|
||||
};
|
||||
|
||||
export default WebGLMap;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/**
|
||||
* @module ol/events/Event
|
||||
*/
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Stripped down implementation of the W3C DOM Level 2 Event interface.
|
||||
@@ -14,45 +15,49 @@
|
||||
* @constructor
|
||||
* @param {string} type Type.
|
||||
*/
|
||||
const Event = function(type) {
|
||||
class Event {
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.propagationStopped;
|
||||
constructor(type) {
|
||||
|
||||
/**
|
||||
* The event type.
|
||||
* @type {string}
|
||||
* @api
|
||||
*/
|
||||
this.type = type;
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.propagationStopped;
|
||||
|
||||
/**
|
||||
* The event target.
|
||||
* @type {Object}
|
||||
* @api
|
||||
*/
|
||||
this.target = null;
|
||||
/**
|
||||
* The event type.
|
||||
* @type {string}
|
||||
* @api
|
||||
*/
|
||||
this.type = type;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Stop event propagation.
|
||||
* @function
|
||||
* @api
|
||||
*/
|
||||
Event.prototype.preventDefault =
|
||||
/**
|
||||
* The event target.
|
||||
* @type {Object}
|
||||
* @api
|
||||
*/
|
||||
this.target = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop event propagation.
|
||||
* @function
|
||||
* @api
|
||||
*/
|
||||
Event.prototype.stopPropagation = function() {
|
||||
preventDefault() {
|
||||
this.propagationStopped = true;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop event propagation.
|
||||
* @function
|
||||
* @api
|
||||
*/
|
||||
stopPropagation() {
|
||||
this.propagationStopped = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -13,10 +13,14 @@ import LogicalNary from '../filter/LogicalNary.js';
|
||||
* @param {...module:ol/format/filter/Filter} conditions Conditions.
|
||||
* @extends {module:ol/format/filter/LogicalNary}
|
||||
*/
|
||||
const And = function(conditions) {
|
||||
const params = ['And'].concat(Array.prototype.slice.call(arguments));
|
||||
LogicalNary.apply(this, params);
|
||||
};
|
||||
class And {
|
||||
|
||||
constructor(conditions) {
|
||||
const params = ['And'].concat(Array.prototype.slice.call(arguments));
|
||||
LogicalNary.apply(this, params);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inherits(And, LogicalNary);
|
||||
|
||||
|
||||
@@ -17,25 +17,29 @@ import Filter from '../filter/Filter.js';
|
||||
* @extends {module:ol/format/filter/Filter}
|
||||
* @api
|
||||
*/
|
||||
const Bbox = function(geometryName, extent, opt_srsName) {
|
||||
class Bbox {
|
||||
|
||||
Filter.call(this, 'BBOX');
|
||||
constructor(geometryName, extent, opt_srsName) {
|
||||
|
||||
/**
|
||||
* @type {!string}
|
||||
*/
|
||||
this.geometryName = geometryName;
|
||||
Filter.call(this, 'BBOX');
|
||||
|
||||
/**
|
||||
* @type {module:ol/extent~Extent}
|
||||
*/
|
||||
this.extent = extent;
|
||||
/**
|
||||
* @type {!string}
|
||||
*/
|
||||
this.geometryName = geometryName;
|
||||
|
||||
/**
|
||||
* @type {string|undefined}
|
||||
*/
|
||||
this.srsName = opt_srsName;
|
||||
};
|
||||
/**
|
||||
* @type {module:ol/extent~Extent}
|
||||
*/
|
||||
this.extent = extent;
|
||||
|
||||
/**
|
||||
* @type {string|undefined}
|
||||
*/
|
||||
this.srsName = opt_srsName;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inherits(Bbox, Filter);
|
||||
|
||||
|
||||
@@ -15,15 +15,19 @@ import Filter from '../filter/Filter.js';
|
||||
* @param {!string} propertyName Name of the context property to compare.
|
||||
* @extends {module:ol/format/filter/Filter}
|
||||
*/
|
||||
const Comparison = function(tagName, propertyName) {
|
||||
class Comparison {
|
||||
|
||||
Filter.call(this, tagName);
|
||||
constructor(tagName, propertyName) {
|
||||
|
||||
/**
|
||||
* @type {!string}
|
||||
*/
|
||||
this.propertyName = propertyName;
|
||||
};
|
||||
Filter.call(this, tagName);
|
||||
|
||||
/**
|
||||
* @type {!string}
|
||||
*/
|
||||
this.propertyName = propertyName;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inherits(Comparison, Filter);
|
||||
|
||||
|
||||
@@ -17,20 +17,25 @@ import Comparison from '../filter/Comparison.js';
|
||||
* @param {boolean=} opt_matchCase Case-sensitive?
|
||||
* @extends {module:ol/format/filter/Comparison}
|
||||
*/
|
||||
const ComparisonBinary = function(tagName, propertyName, expression, opt_matchCase) {
|
||||
class ComparisonBinary {
|
||||
|
||||
Comparison.call(this, tagName, propertyName);
|
||||
constructor(tagName, propertyName, expression, opt_matchCase) {
|
||||
|
||||
/**
|
||||
* @type {!(string|number)}
|
||||
*/
|
||||
this.expression = expression;
|
||||
Comparison.call(this, tagName, propertyName);
|
||||
|
||||
/**
|
||||
* @type {boolean|undefined}
|
||||
*/
|
||||
this.matchCase = opt_matchCase;
|
||||
};
|
||||
/**
|
||||
* @type {!(string|number)}
|
||||
*/
|
||||
this.expression = expression;
|
||||
|
||||
/**
|
||||
* @type {boolean|undefined}
|
||||
*/
|
||||
this.matchCase = opt_matchCase;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inherits(ComparisonBinary, Comparison);
|
||||
|
||||
export default ComparisonBinary;
|
||||
|
||||
@@ -17,11 +17,16 @@ import Spatial from '../filter/Spatial.js';
|
||||
* @extends {module:ol/format/filter/Spatial}
|
||||
* @api
|
||||
*/
|
||||
const Contains = function(geometryName, geometry, opt_srsName) {
|
||||
class Contains {
|
||||
|
||||
Spatial.call(this, 'Contains', geometryName, geometry, opt_srsName);
|
||||
constructor(geometryName, geometry, opt_srsName) {
|
||||
|
||||
};
|
||||
Spatial.call(this, 'Contains', geometryName, geometry, opt_srsName);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inherits(Contains, Spatial);
|
||||
|
||||
export default Contains;
|
||||
|
||||
@@ -15,19 +15,24 @@ import Comparison from '../filter/Comparison.js';
|
||||
* @extends {module:ol/format/filter/Comparison}
|
||||
* @api
|
||||
*/
|
||||
const During = function(propertyName, begin, end) {
|
||||
Comparison.call(this, 'During', propertyName);
|
||||
class During {
|
||||
|
||||
/**
|
||||
* @type {!string}
|
||||
*/
|
||||
this.begin = begin;
|
||||
constructor(propertyName, begin, end) {
|
||||
Comparison.call(this, 'During', propertyName);
|
||||
|
||||
/**
|
||||
* @type {!string}
|
||||
*/
|
||||
this.end = end;
|
||||
};
|
||||
/**
|
||||
* @type {!string}
|
||||
*/
|
||||
this.begin = begin;
|
||||
|
||||
/**
|
||||
* @type {!string}
|
||||
*/
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inherits(During, Comparison);
|
||||
|
||||
export default During;
|
||||
|
||||
@@ -15,9 +15,14 @@ import ComparisonBinary from '../filter/ComparisonBinary.js';
|
||||
* @extends {module:ol/format/filter/ComparisonBinary}
|
||||
* @api
|
||||
*/
|
||||
const EqualTo = function(propertyName, expression, opt_matchCase) {
|
||||
ComparisonBinary.call(this, 'PropertyIsEqualTo', propertyName, expression, opt_matchCase);
|
||||
};
|
||||
class EqualTo {
|
||||
|
||||
constructor(propertyName, expression, opt_matchCase) {
|
||||
ComparisonBinary.call(this, 'PropertyIsEqualTo', propertyName, expression, opt_matchCase);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inherits(EqualTo, ComparisonBinary);
|
||||
|
||||
export default EqualTo;
|
||||
|
||||
@@ -14,9 +14,14 @@ import ComparisonBinary from '../filter/ComparisonBinary.js';
|
||||
* @extends {module:ol/format/filter/ComparisonBinary}
|
||||
* @api
|
||||
*/
|
||||
const GreaterThan = function(propertyName, expression) {
|
||||
ComparisonBinary.call(this, 'PropertyIsGreaterThan', propertyName, expression);
|
||||
};
|
||||
class GreaterThan {
|
||||
|
||||
constructor(propertyName, expression) {
|
||||
ComparisonBinary.call(this, 'PropertyIsGreaterThan', propertyName, expression);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inherits(GreaterThan, ComparisonBinary);
|
||||
|
||||
export default GreaterThan;
|
||||
|
||||
@@ -14,9 +14,14 @@ import ComparisonBinary from '../filter/ComparisonBinary.js';
|
||||
* @extends {module:ol/format/filter/ComparisonBinary}
|
||||
* @api
|
||||
*/
|
||||
const GreaterThanOrEqualTo = function(propertyName, expression) {
|
||||
ComparisonBinary.call(this, 'PropertyIsGreaterThanOrEqualTo', propertyName, expression);
|
||||
};
|
||||
class GreaterThanOrEqualTo {
|
||||
|
||||
constructor(propertyName, expression) {
|
||||
ComparisonBinary.call(this, 'PropertyIsGreaterThanOrEqualTo', propertyName, expression);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inherits(GreaterThanOrEqualTo, ComparisonBinary);
|
||||
|
||||
export default GreaterThanOrEqualTo;
|
||||
|
||||
@@ -17,11 +17,15 @@ import Spatial from '../filter/Spatial.js';
|
||||
* @extends {module:ol/format/filter/Spatial}
|
||||
* @api
|
||||
*/
|
||||
const Intersects = function(geometryName, geometry, opt_srsName) {
|
||||
class Intersects {
|
||||
|
||||
Spatial.call(this, 'Intersects', geometryName, geometry, opt_srsName);
|
||||
constructor(geometryName, geometry, opt_srsName) {
|
||||
|
||||
};
|
||||
Spatial.call(this, 'Intersects', geometryName, geometry, opt_srsName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inherits(Intersects, Spatial);
|
||||
|
||||
export default Intersects;
|
||||
|
||||
@@ -15,19 +15,24 @@ import Comparison from '../filter/Comparison.js';
|
||||
* @extends {module:ol/format/filter/Comparison}
|
||||
* @api
|
||||
*/
|
||||
const IsBetween = function(propertyName, lowerBoundary, upperBoundary) {
|
||||
Comparison.call(this, 'PropertyIsBetween', propertyName);
|
||||
class IsBetween {
|
||||
|
||||
/**
|
||||
* @type {!number}
|
||||
*/
|
||||
this.lowerBoundary = lowerBoundary;
|
||||
constructor(propertyName, lowerBoundary, upperBoundary) {
|
||||
Comparison.call(this, 'PropertyIsBetween', propertyName);
|
||||
|
||||
/**
|
||||
* @type {!number}
|
||||
*/
|
||||
this.upperBoundary = upperBoundary;
|
||||
};
|
||||
/**
|
||||
* @type {!number}
|
||||
*/
|
||||
this.lowerBoundary = lowerBoundary;
|
||||
|
||||
/**
|
||||
* @type {!number}
|
||||
*/
|
||||
this.upperBoundary = upperBoundary;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
inherits(IsBetween, Comparison);
|
||||
|
||||
export default IsBetween;
|
||||
|
||||
@@ -21,34 +21,39 @@ import Comparison from '../filter/Comparison.js';
|
||||
* @extends {module:ol/format/filter/Comparison}
|
||||
* @api
|
||||
*/
|
||||
const IsLike = function(propertyName, pattern, opt_wildCard, opt_singleChar, opt_escapeChar, opt_matchCase) {
|
||||
Comparison.call(this, 'PropertyIsLike', propertyName);
|
||||
class IsLike {
|
||||
|
||||
/**
|
||||
* @type {!string}
|
||||
*/
|
||||
this.pattern = pattern;
|
||||
constructor(propertyName, pattern, opt_wildCard, opt_singleChar, opt_escapeChar, opt_matchCase) {
|
||||
Comparison.call(this, 'PropertyIsLike', propertyName);
|
||||
|
||||
/**
|
||||
* @type {!string}
|
||||
*/
|
||||
this.wildCard = (opt_wildCard !== undefined) ? opt_wildCard : '*';
|
||||
/**
|
||||
* @type {!string}
|
||||
*/
|
||||
this.pattern = pattern;
|
||||
|
||||
/**
|
||||
* @type {!string}
|
||||
*/
|
||||
this.singleChar = (opt_singleChar !== undefined) ? opt_singleChar : '.';
|
||||
/**
|
||||
* @type {!string}
|
||||
*/
|
||||
this.wildCard = (opt_wildCard !== undefined) ? opt_wildCard : '*';
|
||||
|
||||
/**
|
||||
* @type {!string}
|
||||
*/
|
||||
this.escapeChar = (opt_escapeChar !== undefined) ? opt_escapeChar : '!';
|
||||
/**
|
||||
* @type {!string}
|
||||
*/
|
||||
this.singleChar = (opt_singleChar !== undefined) ? opt_singleChar : '.';
|
||||
|
||||
/**
|
||||
* @type {boolean|undefined}
|
||||
*/
|
||||
this.matchCase = opt_matchCase;
|
||||
};
|
||||
/**
|
||||
* @type {!string}
|
||||
*/
|
||||
this.escapeChar = (opt_escapeChar !== undefined) ? opt_escapeChar : '!';
|
||||
|
||||
/**
|
||||
* @type {boolean|undefined}
|
||||
*/
|
||||
this.matchCase = opt_matchCase;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
inherits(IsLike, Comparison);
|
||||
|
||||
export default IsLike;
|
||||
|
||||
@@ -13,9 +13,15 @@ import Comparison from '../filter/Comparison.js';
|
||||
* @extends {module:ol/format/filter/Comparison}
|
||||
* @api
|
||||
*/
|
||||
const IsNull = function(propertyName) {
|
||||
Comparison.call(this, 'PropertyIsNull', propertyName);
|
||||
};
|
||||
class IsNull {
|
||||
|
||||
constructor(propertyName) {
|
||||
Comparison.call(this, 'PropertyIsNull', propertyName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
inherits(IsNull, Comparison);
|
||||
|
||||
export default IsNull;
|
||||
|
||||
@@ -14,9 +14,14 @@ import ComparisonBinary from '../filter/ComparisonBinary.js';
|
||||
* @extends {module:ol/format/filter/ComparisonBinary}
|
||||
* @api
|
||||
*/
|
||||
const LessThan = function(propertyName, expression) {
|
||||
ComparisonBinary.call(this, 'PropertyIsLessThan', propertyName, expression);
|
||||
};
|
||||
class LessThan {
|
||||
|
||||
constructor(propertyName, expression) {
|
||||
ComparisonBinary.call(this, 'PropertyIsLessThan', propertyName, expression);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inherits(LessThan, ComparisonBinary);
|
||||
|
||||
export default LessThan;
|
||||
|
||||
@@ -14,9 +14,14 @@ import ComparisonBinary from '../filter/ComparisonBinary.js';
|
||||
* @extends {module:ol/format/filter/ComparisonBinary}
|
||||
* @api
|
||||
*/
|
||||
const LessThanOrEqualTo = function(propertyName, expression) {
|
||||
ComparisonBinary.call(this, 'PropertyIsLessThanOrEqualTo', propertyName, expression);
|
||||
};
|
||||
class LessThanOrEqualTo {
|
||||
|
||||
constructor(propertyName, expression) {
|
||||
ComparisonBinary.call(this, 'PropertyIsLessThanOrEqualTo', propertyName, expression);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inherits(LessThanOrEqualTo, ComparisonBinary);
|
||||
|
||||
export default LessThanOrEqualTo;
|
||||
|
||||
@@ -16,16 +16,21 @@ import Filter from '../filter/Filter.js';
|
||||
* @param {...module:ol/format/filter/Filter} conditions Conditions.
|
||||
* @extends {module:ol/format/filter/Filter}
|
||||
*/
|
||||
const LogicalNary = function(tagName, conditions) {
|
||||
class LogicalNary {
|
||||
|
||||
Filter.call(this, tagName);
|
||||
constructor(tagName, conditions) {
|
||||
|
||||
/**
|
||||
* @type {Array.<module:ol/format/filter/Filter>}
|
||||
*/
|
||||
this.conditions = Array.prototype.slice.call(arguments, 1);
|
||||
assert(this.conditions.length >= 2, 57); // At least 2 conditions are required.
|
||||
};
|
||||
Filter.call(this, tagName);
|
||||
|
||||
/**
|
||||
* @type {Array.<module:ol/format/filter/Filter>}
|
||||
*/
|
||||
this.conditions = Array.prototype.slice.call(arguments, 1);
|
||||
assert(this.conditions.length >= 2, 57); // At least 2 conditions are required.
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inherits(LogicalNary, Filter);
|
||||
|
||||
export default LogicalNary;
|
||||
|
||||
@@ -13,15 +13,20 @@ import Filter from '../filter/Filter.js';
|
||||
* @extends {module:ol/format/filter/Filter}
|
||||
* @api
|
||||
*/
|
||||
const Not = function(condition) {
|
||||
class Not {
|
||||
|
||||
Filter.call(this, 'Not');
|
||||
constructor(condition) {
|
||||
|
||||
/**
|
||||
* @type {!module:ol/format/filter/Filter}
|
||||
*/
|
||||
this.condition = condition;
|
||||
};
|
||||
Filter.call(this, 'Not');
|
||||
|
||||
/**
|
||||
* @type {!module:ol/format/filter/Filter}
|
||||
*/
|
||||
this.condition = condition;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inherits(Not, Filter);
|
||||
export default Not;
|
||||
|
||||
@@ -15,9 +15,14 @@ import ComparisonBinary from '../filter/ComparisonBinary.js';
|
||||
* @extends {module:ol/format/filter/ComparisonBinary}
|
||||
* @api
|
||||
*/
|
||||
const NotEqualTo = function(propertyName, expression, opt_matchCase) {
|
||||
ComparisonBinary.call(this, 'PropertyIsNotEqualTo', propertyName, expression, opt_matchCase);
|
||||
};
|
||||
class NotEqualTo {
|
||||
|
||||
constructor(propertyName, expression, opt_matchCase) {
|
||||
ComparisonBinary.call(this, 'PropertyIsNotEqualTo', propertyName, expression, opt_matchCase);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inherits(NotEqualTo, ComparisonBinary);
|
||||
|
||||
export default NotEqualTo;
|
||||
|
||||
@@ -13,10 +13,15 @@ import LogicalNary from '../filter/LogicalNary.js';
|
||||
* @extends {module:ol/format/filter/LogicalNary}
|
||||
* @api
|
||||
*/
|
||||
const Or = function(conditions) {
|
||||
const params = ['Or'].concat(Array.prototype.slice.call(arguments));
|
||||
LogicalNary.apply(this, params);
|
||||
};
|
||||
class Or {
|
||||
|
||||
constructor(conditions) {
|
||||
const params = ['Or'].concat(Array.prototype.slice.call(arguments));
|
||||
LogicalNary.apply(this, params);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inherits(Or, LogicalNary);
|
||||
|
||||
export default Or;
|
||||
|
||||
@@ -19,25 +19,29 @@ import Filter from '../filter/Filter.js';
|
||||
* set on geometries when this is not provided.
|
||||
* @extends {module:ol/format/filter/Filter}
|
||||
*/
|
||||
const Spatial = function(tagName, geometryName, geometry, opt_srsName) {
|
||||
class Spatial {
|
||||
|
||||
Filter.call(this, tagName);
|
||||
constructor(tagName, geometryName, geometry, opt_srsName) {
|
||||
|
||||
/**
|
||||
* @type {!string}
|
||||
*/
|
||||
this.geometryName = geometryName || 'the_geom';
|
||||
Filter.call(this, tagName);
|
||||
|
||||
/**
|
||||
* @type {module:ol/geom/Geometry}
|
||||
*/
|
||||
this.geometry = geometry;
|
||||
/**
|
||||
* @type {!string}
|
||||
*/
|
||||
this.geometryName = geometryName || 'the_geom';
|
||||
|
||||
/**
|
||||
* @type {string|undefined}
|
||||
*/
|
||||
this.srsName = opt_srsName;
|
||||
};
|
||||
/**
|
||||
* @type {module:ol/geom/Geometry}
|
||||
*/
|
||||
this.geometry = geometry;
|
||||
|
||||
/**
|
||||
* @type {string|undefined}
|
||||
*/
|
||||
this.srsName = opt_srsName;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inherits(Spatial, Filter);
|
||||
|
||||
|
||||
@@ -17,11 +17,14 @@ import Spatial from '../filter/Spatial.js';
|
||||
* @extends {module:ol/format/filter/Spatial}
|
||||
* @api
|
||||
*/
|
||||
const Within = function(geometryName, geometry, opt_srsName) {
|
||||
class Within {
|
||||
|
||||
Spatial.call(this, 'Within', geometryName, geometry, opt_srsName);
|
||||
constructor(geometryName, geometry, opt_srsName) {
|
||||
Spatial.call(this, 'Within', geometryName, geometry, opt_srsName);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
inherits(Within, Spatial);
|
||||
|
||||
export default Within;
|
||||
|
||||
@@ -22,27 +22,31 @@ import Interaction, {zoomByDelta} from '../interaction/Interaction.js';
|
||||
* @param {module:ol/interaction/DoubleClickZoom~Options=} opt_options Options.
|
||||
* @api
|
||||
*/
|
||||
const DoubleClickZoom = function(opt_options) {
|
||||
class DoubleClickZoom {
|
||||
|
||||
const options = opt_options ? opt_options : {};
|
||||
constructor(opt_options) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.delta_ = options.delta ? options.delta : 1;
|
||||
const options = opt_options ? opt_options : {};
|
||||
|
||||
Interaction.call(this, {
|
||||
handleEvent: handleEvent
|
||||
});
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.delta_ = options.delta ? options.delta : 1;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.duration_ = options.duration !== undefined ? options.duration : 250;
|
||||
Interaction.call(this, {
|
||||
handleEvent: handleEvent
|
||||
});
|
||||
|
||||
};
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.duration_ = options.duration !== undefined ? options.duration : 250;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inherits(DoubleClickZoom, Interaction);
|
||||
|
||||
|
||||
@@ -50,32 +50,37 @@ const DragAndDropEventType = {
|
||||
* @param {Array.<module:ol/Feature>=} opt_features Features.
|
||||
* @param {module:ol/proj/Projection=} opt_projection Projection.
|
||||
*/
|
||||
const DragAndDropEvent = function(type, file, opt_features, opt_projection) {
|
||||
class DragAndDropEvent {
|
||||
|
||||
Event.call(this, type);
|
||||
constructor(type, file, opt_features, opt_projection) {
|
||||
|
||||
/**
|
||||
* The features parsed from dropped data.
|
||||
* @type {Array.<module:ol/Feature>|undefined}
|
||||
* @api
|
||||
*/
|
||||
this.features = opt_features;
|
||||
Event.call(this, type);
|
||||
|
||||
/**
|
||||
* The dropped file.
|
||||
* @type {File}
|
||||
* @api
|
||||
*/
|
||||
this.file = file;
|
||||
/**
|
||||
* The features parsed from dropped data.
|
||||
* @type {Array.<module:ol/Feature>|undefined}
|
||||
* @api
|
||||
*/
|
||||
this.features = opt_features;
|
||||
|
||||
/**
|
||||
* The feature projection.
|
||||
* @type {module:ol/proj/Projection|undefined}
|
||||
* @api
|
||||
*/
|
||||
this.projection = opt_projection;
|
||||
/**
|
||||
* The dropped file.
|
||||
* @type {File}
|
||||
* @api
|
||||
*/
|
||||
this.file = file;
|
||||
|
||||
/**
|
||||
* The feature projection.
|
||||
* @type {module:ol/proj/Projection|undefined}
|
||||
* @api
|
||||
*/
|
||||
this.projection = opt_projection;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
inherits(DragAndDropEvent, Event);
|
||||
|
||||
|
||||
|
||||
@@ -70,25 +70,29 @@ const DragBoxEventType = {
|
||||
* @extends {module:ol/events/Event}
|
||||
* @constructor
|
||||
*/
|
||||
const DragBoxEvent = function(type, coordinate, mapBrowserEvent) {
|
||||
Event.call(this, type);
|
||||
class DragBoxEvent {
|
||||
|
||||
/**
|
||||
* The coordinate of the drag event.
|
||||
* @const
|
||||
* @type {module:ol/coordinate~Coordinate}
|
||||
* @api
|
||||
*/
|
||||
this.coordinate = coordinate;
|
||||
constructor(type, coordinate, mapBrowserEvent) {
|
||||
Event.call(this, type);
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {module:ol/MapBrowserEvent}
|
||||
* @api
|
||||
*/
|
||||
this.mapBrowserEvent = mapBrowserEvent;
|
||||
/**
|
||||
* The coordinate of the drag event.
|
||||
* @const
|
||||
* @type {module:ol/coordinate~Coordinate}
|
||||
* @api
|
||||
*/
|
||||
this.coordinate = coordinate;
|
||||
|
||||
};
|
||||
/**
|
||||
* @const
|
||||
* @type {module:ol/MapBrowserEvent}
|
||||
* @api
|
||||
*/
|
||||
this.mapBrowserEvent = mapBrowserEvent;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inherits(DragBoxEvent, Event);
|
||||
|
||||
@@ -111,56 +115,56 @@ inherits(DragBoxEvent, Event);
|
||||
* @api
|
||||
*/
|
||||
class DragBox {
|
||||
constructor(opt_options) {
|
||||
constructor(opt_options) {
|
||||
|
||||
PointerInteraction.call(this, {
|
||||
handleDownEvent: handleDownEvent,
|
||||
handleDragEvent: handleDragEvent,
|
||||
handleUpEvent: handleUpEvent
|
||||
});
|
||||
PointerInteraction.call(this, {
|
||||
handleDownEvent: handleDownEvent,
|
||||
handleDragEvent: handleDragEvent,
|
||||
handleUpEvent: handleUpEvent
|
||||
});
|
||||
|
||||
const options = opt_options ? opt_options : {};
|
||||
const options = opt_options ? opt_options : {};
|
||||
|
||||
/**
|
||||
/**
|
||||
* @type {module:ol/render/Box}
|
||||
* @private
|
||||
*/
|
||||
this.box_ = new RenderBox(options.className || 'ol-dragbox');
|
||||
this.box_ = new RenderBox(options.className || 'ol-dragbox');
|
||||
|
||||
/**
|
||||
/**
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.minArea_ = options.minArea !== undefined ? options.minArea : 64;
|
||||
this.minArea_ = options.minArea !== undefined ? options.minArea : 64;
|
||||
|
||||
/**
|
||||
/**
|
||||
* @type {module:ol~Pixel}
|
||||
* @private
|
||||
*/
|
||||
this.startPixel_ = null;
|
||||
this.startPixel_ = null;
|
||||
|
||||
/**
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/events/condition~Condition}
|
||||
*/
|
||||
this.condition_ = options.condition ? options.condition : always;
|
||||
this.condition_ = options.condition ? options.condition : always;
|
||||
|
||||
/**
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/interaction/DragBox~EndCondition}
|
||||
*/
|
||||
this.boxEndCondition_ = options.boxEndCondition ?
|
||||
options.boxEndCondition : defaultBoxEndCondition;
|
||||
}
|
||||
this.boxEndCondition_ = options.boxEndCondition ?
|
||||
options.boxEndCondition : defaultBoxEndCondition;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Returns geometry of last drawn box.
|
||||
* @return {module:ol/geom/Polygon} Geometry.
|
||||
* @api
|
||||
*/
|
||||
getGeometry() {
|
||||
return this.box_.getGeometry();
|
||||
}
|
||||
getGeometry() {
|
||||
return this.box_.getGeometry();
|
||||
}
|
||||
}
|
||||
|
||||
inherits(DragBox, PointerInteraction);
|
||||
|
||||
@@ -28,45 +28,48 @@ import PointerInteraction, {centroid as centroidFromPointers} from '../interacti
|
||||
* @param {module:ol/interaction/DragPan~Options=} opt_options Options.
|
||||
* @api
|
||||
*/
|
||||
const DragPan = function(opt_options) {
|
||||
class DragPan {
|
||||
constructor(opt_options) {
|
||||
|
||||
PointerInteraction.call(this, {
|
||||
handleDownEvent: handleDownEvent,
|
||||
handleDragEvent: handleDragEvent,
|
||||
handleUpEvent: handleUpEvent
|
||||
});
|
||||
PointerInteraction.call(this, {
|
||||
handleDownEvent: handleDownEvent,
|
||||
handleDragEvent: handleDragEvent,
|
||||
handleUpEvent: handleUpEvent
|
||||
});
|
||||
|
||||
const options = opt_options ? opt_options : {};
|
||||
const options = opt_options ? opt_options : {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/Kinetic|undefined}
|
||||
*/
|
||||
this.kinetic_ = options.kinetic;
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/Kinetic|undefined}
|
||||
*/
|
||||
this.kinetic_ = options.kinetic;
|
||||
|
||||
/**
|
||||
* @type {module:ol~Pixel}
|
||||
*/
|
||||
this.lastCentroid = null;
|
||||
/**
|
||||
* @type {module:ol~Pixel}
|
||||
*/
|
||||
this.lastCentroid = null;
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.lastPointersCount_;
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.lastPointersCount_;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/events/condition~Condition}
|
||||
*/
|
||||
this.condition_ = options.condition ? options.condition : noModifierKeys;
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/events/condition~Condition}
|
||||
*/
|
||||
this.condition_ = options.condition ? options.condition : noModifierKeys;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.noKinetic_ = false;
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.noKinetic_ = false;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inherits(DragPan, PointerInteraction);
|
||||
|
||||
|
||||
@@ -33,34 +33,39 @@ import PointerInteraction from '../interaction/Pointer.js';
|
||||
* @param {module:ol/interaction/DragRotate~Options=} opt_options Options.
|
||||
* @api
|
||||
*/
|
||||
const DragRotate = function(opt_options) {
|
||||
class DragRotate {
|
||||
|
||||
const options = opt_options ? opt_options : {};
|
||||
constructor(opt_options) {
|
||||
|
||||
PointerInteraction.call(this, {
|
||||
handleDownEvent: handleDownEvent,
|
||||
handleDragEvent: handleDragEvent,
|
||||
handleUpEvent: handleUpEvent
|
||||
});
|
||||
const options = opt_options ? opt_options : {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/events/condition~Condition}
|
||||
*/
|
||||
this.condition_ = options.condition ? options.condition : altShiftKeysOnly;
|
||||
PointerInteraction.call(this, {
|
||||
handleDownEvent: handleDownEvent,
|
||||
handleDragEvent: handleDragEvent,
|
||||
handleUpEvent: handleUpEvent
|
||||
});
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number|undefined}
|
||||
*/
|
||||
this.lastAngle_ = undefined;
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/events/condition~Condition}
|
||||
*/
|
||||
this.condition_ = options.condition ? options.condition : altShiftKeysOnly;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.duration_ = options.duration !== undefined ? options.duration : 250;
|
||||
};
|
||||
/**
|
||||
* @private
|
||||
* @type {number|undefined}
|
||||
*/
|
||||
this.lastAngle_ = undefined;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.duration_ = options.duration !== undefined ? options.duration : 250;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inherits(DragRotate, PointerInteraction);
|
||||
|
||||
|
||||
@@ -34,47 +34,51 @@ import PointerInteraction from '../interaction/Pointer.js';
|
||||
* @param {module:ol/interaction/DragRotateAndZoom~Options=} opt_options Options.
|
||||
* @api
|
||||
*/
|
||||
const DragRotateAndZoom = function(opt_options) {
|
||||
class DragRotateAndZoom {
|
||||
|
||||
const options = opt_options ? opt_options : {};
|
||||
constructor(opt_options) {
|
||||
|
||||
PointerInteraction.call(this, {
|
||||
handleDownEvent: handleDownEvent,
|
||||
handleDragEvent: handleDragEvent,
|
||||
handleUpEvent: handleUpEvent
|
||||
});
|
||||
const options = opt_options ? opt_options : {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/events/condition~Condition}
|
||||
*/
|
||||
this.condition_ = options.condition ? options.condition : shiftKeyOnly;
|
||||
PointerInteraction.call(this, {
|
||||
handleDownEvent: handleDownEvent,
|
||||
handleDragEvent: handleDragEvent,
|
||||
handleUpEvent: handleUpEvent
|
||||
});
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number|undefined}
|
||||
*/
|
||||
this.lastAngle_ = undefined;
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/events/condition~Condition}
|
||||
*/
|
||||
this.condition_ = options.condition ? options.condition : shiftKeyOnly;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number|undefined}
|
||||
*/
|
||||
this.lastMagnitude_ = undefined;
|
||||
/**
|
||||
* @private
|
||||
* @type {number|undefined}
|
||||
*/
|
||||
this.lastAngle_ = undefined;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.lastScaleDelta_ = 0;
|
||||
/**
|
||||
* @private
|
||||
* @type {number|undefined}
|
||||
*/
|
||||
this.lastMagnitude_ = undefined;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.duration_ = options.duration !== undefined ? options.duration : 400;
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.lastScaleDelta_ = 0;
|
||||
|
||||
};
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.duration_ = options.duration !== undefined ? options.duration : 400;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inherits(DragRotateAndZoom, PointerInteraction);
|
||||
|
||||
|
||||
@@ -134,18 +134,22 @@ const DrawEventType = {
|
||||
* @param {module:ol/interaction/Draw~DrawEventType} type Type.
|
||||
* @param {module:ol/Feature} feature The feature drawn.
|
||||
*/
|
||||
const DrawEvent = function(type, feature) {
|
||||
class DrawEvent {
|
||||
|
||||
Event.call(this, type);
|
||||
constructor(type, feature) {
|
||||
|
||||
/**
|
||||
* The feature being drawn.
|
||||
* @type {module:ol/Feature}
|
||||
* @api
|
||||
*/
|
||||
this.feature = feature;
|
||||
Event.call(this, type);
|
||||
|
||||
};
|
||||
/**
|
||||
* The feature being drawn.
|
||||
* @type {module:ol/Feature}
|
||||
* @api
|
||||
*/
|
||||
this.feature = feature;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inherits(DrawEvent, Event);
|
||||
|
||||
|
||||
@@ -56,17 +56,21 @@ const ExtentEventType = {
|
||||
* @param {module:ol/extent~Extent} extent the new extent
|
||||
* @extends {module:ol/events/Event}
|
||||
*/
|
||||
const ExtentInteractionEvent = function(extent) {
|
||||
Event.call(this, ExtentEventType.EXTENTCHANGED);
|
||||
class ExtentInteractionEvent {
|
||||
|
||||
/**
|
||||
* The current extent.
|
||||
* @type {module:ol/extent~Extent}
|
||||
* @api
|
||||
*/
|
||||
this.extent = extent;
|
||||
constructor(extent) {
|
||||
Event.call(this, ExtentEventType.EXTENTCHANGED);
|
||||
|
||||
/**
|
||||
* The current extent.
|
||||
* @type {module:ol/extent~Extent}
|
||||
* @api
|
||||
*/
|
||||
this.extent = extent;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
inherits(ExtentInteractionEvent, Event);
|
||||
|
||||
|
||||
|
||||
@@ -39,45 +39,49 @@ import Interaction, {pan} from '../interaction/Interaction.js';
|
||||
* @param {module:ol/interaction/KeyboardPan~Options=} opt_options Options.
|
||||
* @api
|
||||
*/
|
||||
const KeyboardPan = function(opt_options) {
|
||||
class KeyboardPan {
|
||||
|
||||
Interaction.call(this, {
|
||||
handleEvent: handleEvent
|
||||
});
|
||||
constructor(opt_options) {
|
||||
|
||||
const options = opt_options || {};
|
||||
Interaction.call(this, {
|
||||
handleEvent: handleEvent
|
||||
});
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {module:ol/MapBrowserEvent} mapBrowserEvent Browser event.
|
||||
* @return {boolean} Combined condition result.
|
||||
*/
|
||||
this.defaultCondition_ = function(mapBrowserEvent) {
|
||||
return noModifierKeys(mapBrowserEvent) &&
|
||||
targetNotEditable(mapBrowserEvent);
|
||||
};
|
||||
const options = opt_options || {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/events/condition~Condition}
|
||||
*/
|
||||
this.condition_ = options.condition !== undefined ?
|
||||
options.condition : this.defaultCondition_;
|
||||
/**
|
||||
* @private
|
||||
* @param {module:ol/MapBrowserEvent} mapBrowserEvent Browser event.
|
||||
* @return {boolean} Combined condition result.
|
||||
*/
|
||||
this.defaultCondition_ = function(mapBrowserEvent) {
|
||||
return noModifierKeys(mapBrowserEvent) &&
|
||||
targetNotEditable(mapBrowserEvent);
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.duration_ = options.duration !== undefined ? options.duration : 100;
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/events/condition~Condition}
|
||||
*/
|
||||
this.condition_ = options.condition !== undefined ?
|
||||
options.condition : this.defaultCondition_;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.pixelDelta_ = options.pixelDelta !== undefined ?
|
||||
options.pixelDelta : 128;
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.duration_ = options.duration !== undefined ? options.duration : 100;
|
||||
|
||||
};
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.pixelDelta_ = options.pixelDelta !== undefined ?
|
||||
options.pixelDelta : 128;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inherits(KeyboardPan, Interaction);
|
||||
|
||||
|
||||
@@ -35,33 +35,37 @@ import Interaction, {zoomByDelta} from '../interaction/Interaction.js';
|
||||
* @extends {module:ol/interaction/Interaction}
|
||||
* @api
|
||||
*/
|
||||
const KeyboardZoom = function(opt_options) {
|
||||
class KeyboardZoom {
|
||||
|
||||
Interaction.call(this, {
|
||||
handleEvent: handleEvent
|
||||
});
|
||||
constructor(opt_options) {
|
||||
|
||||
const options = opt_options ? opt_options : {};
|
||||
Interaction.call(this, {
|
||||
handleEvent: handleEvent
|
||||
});
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/events/condition~Condition}
|
||||
*/
|
||||
this.condition_ = options.condition ? options.condition : targetNotEditable;
|
||||
const options = opt_options ? opt_options : {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.delta_ = options.delta ? options.delta : 1;
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/events/condition~Condition}
|
||||
*/
|
||||
this.condition_ = options.condition ? options.condition : targetNotEditable;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.duration_ = options.duration !== undefined ? options.duration : 100;
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.delta_ = options.delta ? options.delta : 1;
|
||||
|
||||
};
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.duration_ = options.duration !== undefined ? options.duration : 100;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inherits(KeyboardZoom, Interaction);
|
||||
|
||||
|
||||
@@ -99,24 +99,29 @@ const ModifyEventType = {
|
||||
* @param {module:ol/MapBrowserPointerEvent} mapBrowserPointerEvent
|
||||
* Associated {@link module:ol/MapBrowserPointerEvent}.
|
||||
*/
|
||||
export const ModifyEvent = function(type, features, mapBrowserPointerEvent) {
|
||||
export class ModifyEvent {
|
||||
|
||||
Event.call(this, type);
|
||||
constructor(type, features, mapBrowserPointerEvent) {
|
||||
|
||||
/**
|
||||
* The features being modified.
|
||||
* @type {module:ol/Collection.<module:ol/Feature>}
|
||||
* @api
|
||||
*/
|
||||
this.features = features;
|
||||
Event.call(this, type);
|
||||
|
||||
/**
|
||||
* Associated {@link module:ol/MapBrowserEvent}.
|
||||
* @type {module:ol/MapBrowserEvent}
|
||||
* @api
|
||||
*/
|
||||
this.mapBrowserEvent = mapBrowserPointerEvent;
|
||||
};
|
||||
/**
|
||||
* The features being modified.
|
||||
* @type {module:ol/Collection.<module:ol/Feature>}
|
||||
* @api
|
||||
*/
|
||||
this.features = features;
|
||||
|
||||
/**
|
||||
* Associated {@link module:ol/MapBrowserEvent}.
|
||||
* @type {module:ol/MapBrowserEvent}
|
||||
* @api
|
||||
*/
|
||||
this.mapBrowserEvent = mapBrowserPointerEvent;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inherits(ModifyEvent, Event);
|
||||
|
||||
|
||||
@@ -27,53 +27,57 @@ import {disable} from '../rotationconstraint.js';
|
||||
* @param {module:ol/interaction/PinchRotate~Options=} opt_options Options.
|
||||
* @api
|
||||
*/
|
||||
const PinchRotate = function(opt_options) {
|
||||
class PinchRotate {
|
||||
|
||||
PointerInteraction.call(this, {
|
||||
handleDownEvent: handleDownEvent,
|
||||
handleDragEvent: handleDragEvent,
|
||||
handleUpEvent: handleUpEvent
|
||||
});
|
||||
constructor(opt_options) {
|
||||
|
||||
const options = opt_options || {};
|
||||
PointerInteraction.call(this, {
|
||||
handleDownEvent: handleDownEvent,
|
||||
handleDragEvent: handleDragEvent,
|
||||
handleUpEvent: handleUpEvent
|
||||
});
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/coordinate~Coordinate}
|
||||
*/
|
||||
this.anchor_ = null;
|
||||
const options = opt_options || {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number|undefined}
|
||||
*/
|
||||
this.lastAngle_ = undefined;
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/coordinate~Coordinate}
|
||||
*/
|
||||
this.anchor_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.rotating_ = false;
|
||||
/**
|
||||
* @private
|
||||
* @type {number|undefined}
|
||||
*/
|
||||
this.lastAngle_ = undefined;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.rotationDelta_ = 0.0;
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.rotating_ = false;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.threshold_ = options.threshold !== undefined ? options.threshold : 0.3;
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.rotationDelta_ = 0.0;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.duration_ = options.duration !== undefined ? options.duration : 250;
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.threshold_ = options.threshold !== undefined ? options.threshold : 0.3;
|
||||
|
||||
};
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.duration_ = options.duration !== undefined ? options.duration : 250;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inherits(PinchRotate, PointerInteraction);
|
||||
|
||||
|
||||
@@ -26,47 +26,51 @@ import PointerInteraction, {centroid as centroidFromPointers} from '../interacti
|
||||
* @param {module:ol/interaction/PinchZoom~Options=} opt_options Options.
|
||||
* @api
|
||||
*/
|
||||
const PinchZoom = function(opt_options) {
|
||||
class PinchZoom {
|
||||
|
||||
PointerInteraction.call(this, {
|
||||
handleDownEvent: handleDownEvent,
|
||||
handleDragEvent: handleDragEvent,
|
||||
handleUpEvent: handleUpEvent
|
||||
});
|
||||
constructor(opt_options) {
|
||||
|
||||
const options = opt_options ? opt_options : {};
|
||||
PointerInteraction.call(this, {
|
||||
handleDownEvent: handleDownEvent,
|
||||
handleDragEvent: handleDragEvent,
|
||||
handleUpEvent: handleUpEvent
|
||||
});
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.constrainResolution_ = options.constrainResolution || false;
|
||||
const options = opt_options ? opt_options : {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/coordinate~Coordinate}
|
||||
*/
|
||||
this.anchor_ = null;
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.constrainResolution_ = options.constrainResolution || false;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.duration_ = options.duration !== undefined ? options.duration : 400;
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/coordinate~Coordinate}
|
||||
*/
|
||||
this.anchor_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number|undefined}
|
||||
*/
|
||||
this.lastDistance_ = undefined;
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.duration_ = options.duration !== undefined ? options.duration : 400;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.lastScaleDelta_ = 1;
|
||||
/**
|
||||
* @private
|
||||
* @type {number|undefined}
|
||||
*/
|
||||
this.lastDistance_ = undefined;
|
||||
|
||||
};
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.lastScaleDelta_ = 1;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inherits(PinchZoom, PointerInteraction);
|
||||
|
||||
|
||||
@@ -110,30 +110,35 @@ const SelectEventType = {
|
||||
* @extends {module:ol/events/Event}
|
||||
* @constructor
|
||||
*/
|
||||
const SelectEvent = function(type, selected, deselected, mapBrowserEvent) {
|
||||
Event.call(this, type);
|
||||
class SelectEvent {
|
||||
|
||||
/**
|
||||
* Selected features array.
|
||||
* @type {Array.<module:ol/Feature>}
|
||||
* @api
|
||||
*/
|
||||
this.selected = selected;
|
||||
constructor(type, selected, deselected, mapBrowserEvent) {
|
||||
Event.call(this, type);
|
||||
|
||||
/**
|
||||
* Deselected features array.
|
||||
* @type {Array.<module:ol/Feature>}
|
||||
* @api
|
||||
*/
|
||||
this.deselected = deselected;
|
||||
/**
|
||||
* Selected features array.
|
||||
* @type {Array.<module:ol/Feature>}
|
||||
* @api
|
||||
*/
|
||||
this.selected = selected;
|
||||
|
||||
/**
|
||||
* Associated {@link module:ol/MapBrowserEvent}.
|
||||
* @type {module:ol/MapBrowserEvent}
|
||||
* @api
|
||||
*/
|
||||
this.mapBrowserEvent = mapBrowserEvent;
|
||||
};
|
||||
/**
|
||||
* Deselected features array.
|
||||
* @type {Array.<module:ol/Feature>}
|
||||
* @api
|
||||
*/
|
||||
this.deselected = deselected;
|
||||
|
||||
/**
|
||||
* Associated {@link module:ol/MapBrowserEvent}.
|
||||
* @type {module:ol/MapBrowserEvent}
|
||||
* @api
|
||||
*/
|
||||
this.mapBrowserEvent = mapBrowserEvent;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inherits(SelectEvent, Event);
|
||||
|
||||
|
||||
@@ -63,25 +63,30 @@ const TranslateEventType = {
|
||||
* @param {module:ol/Collection.<module:ol/Feature>} features The features translated.
|
||||
* @param {module:ol/coordinate~Coordinate} coordinate The event coordinate.
|
||||
*/
|
||||
export const TranslateEvent = function(type, features, coordinate) {
|
||||
export class TranslateEvent {
|
||||
|
||||
Event.call(this, type);
|
||||
constructor(type, features, coordinate) {
|
||||
|
||||
/**
|
||||
* The features being translated.
|
||||
* @type {module:ol/Collection.<module:ol/Feature>}
|
||||
* @api
|
||||
*/
|
||||
this.features = features;
|
||||
Event.call(this, type);
|
||||
|
||||
/**
|
||||
* The coordinate of the drag event.
|
||||
* @const
|
||||
* @type {module:ol/coordinate~Coordinate}
|
||||
* @api
|
||||
*/
|
||||
this.coordinate = coordinate;
|
||||
};
|
||||
/**
|
||||
* The features being translated.
|
||||
* @type {module:ol/Collection.<module:ol/Feature>}
|
||||
* @api
|
||||
*/
|
||||
this.features = features;
|
||||
|
||||
/**
|
||||
* The coordinate of the drag event.
|
||||
* @const
|
||||
* @type {module:ol/coordinate~Coordinate}
|
||||
* @api
|
||||
*/
|
||||
this.coordinate = coordinate;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inherits(TranslateEvent, Event);
|
||||
|
||||
|
||||
@@ -40,18 +40,22 @@ import Layer from '../layer/Layer.js';
|
||||
* @param {module:ol/layer/Image~Options=} opt_options Layer options.
|
||||
* @api
|
||||
*/
|
||||
const ImageLayer = function(opt_options) {
|
||||
const options = opt_options ? opt_options : {};
|
||||
Layer.call(this, /** @type {module:ol/layer/Layer~Options} */ (options));
|
||||
class ImageLayer {
|
||||
|
||||
/**
|
||||
* The layer type.
|
||||
* @protected
|
||||
* @type {module:ol/LayerType}
|
||||
*/
|
||||
this.type = LayerType.IMAGE;
|
||||
constructor(opt_options) {
|
||||
const options = opt_options ? opt_options : {};
|
||||
Layer.call(this, /** @type {module:ol/layer/Layer~Options} */ (options));
|
||||
|
||||
};
|
||||
/**
|
||||
* The layer type.
|
||||
* @protected
|
||||
* @type {module:ol/LayerType}
|
||||
*/
|
||||
this.type = LayerType.IMAGE;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inherits(ImageLayer, Layer);
|
||||
|
||||
|
||||
@@ -55,134 +55,134 @@ import {METERS_PER_UNIT} from '../proj/Units.js';
|
||||
* @api
|
||||
*/
|
||||
class Projection {
|
||||
constructor(options) {
|
||||
/**
|
||||
constructor(options) {
|
||||
/**
|
||||
* @private
|
||||
* @type {string}
|
||||
*/
|
||||
this.code_ = options.code;
|
||||
this.code_ = options.code;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Units of projected coordinates. When set to `TILE_PIXELS`, a
|
||||
* `this.extent_` and `this.worldExtent_` must be configured properly for each
|
||||
* tile.
|
||||
* @private
|
||||
* @type {module:ol/proj/Units}
|
||||
*/
|
||||
this.units_ = /** @type {module:ol/proj/Units} */ (options.units);
|
||||
this.units_ = /** @type {module:ol/proj/Units} */ (options.units);
|
||||
|
||||
/**
|
||||
/**
|
||||
* Validity extent of the projection in projected coordinates. For projections
|
||||
* with `TILE_PIXELS` units, this is the extent of the tile in
|
||||
* tile pixel space.
|
||||
* @private
|
||||
* @type {module:ol/extent~Extent}
|
||||
*/
|
||||
this.extent_ = options.extent !== undefined ? options.extent : null;
|
||||
this.extent_ = options.extent !== undefined ? options.extent : null;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Extent of the world in EPSG:4326. For projections with
|
||||
* `TILE_PIXELS` units, this is the extent of the tile in
|
||||
* projected coordinate space.
|
||||
* @private
|
||||
* @type {module:ol/extent~Extent}
|
||||
*/
|
||||
this.worldExtent_ = options.worldExtent !== undefined ?
|
||||
options.worldExtent : null;
|
||||
this.worldExtent_ = options.worldExtent !== undefined ?
|
||||
options.worldExtent : null;
|
||||
|
||||
/**
|
||||
/**
|
||||
* @private
|
||||
* @type {string}
|
||||
*/
|
||||
this.axisOrientation_ = options.axisOrientation !== undefined ?
|
||||
options.axisOrientation : 'enu';
|
||||
this.axisOrientation_ = options.axisOrientation !== undefined ?
|
||||
options.axisOrientation : 'enu';
|
||||
|
||||
/**
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.global_ = options.global !== undefined ? options.global : false;
|
||||
this.global_ = options.global !== undefined ? options.global : false;
|
||||
|
||||
/**
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.canWrapX_ = !!(this.global_ && this.extent_);
|
||||
this.canWrapX_ = !!(this.global_ && this.extent_);
|
||||
|
||||
/**
|
||||
/**
|
||||
* @private
|
||||
* @type {function(number, module:ol/coordinate~Coordinate):number|undefined}
|
||||
*/
|
||||
this.getPointResolutionFunc_ = options.getPointResolution;
|
||||
this.getPointResolutionFunc_ = options.getPointResolution;
|
||||
|
||||
/**
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/tilegrid/TileGrid}
|
||||
*/
|
||||
this.defaultTileGrid_ = null;
|
||||
this.defaultTileGrid_ = null;
|
||||
|
||||
/**
|
||||
/**
|
||||
* @private
|
||||
* @type {number|undefined}
|
||||
*/
|
||||
this.metersPerUnit_ = options.metersPerUnit;
|
||||
}
|
||||
this.metersPerUnit_ = options.metersPerUnit;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* @return {boolean} The projection is suitable for wrapping the x-axis
|
||||
*/
|
||||
canWrapX() {
|
||||
return this.canWrapX_;
|
||||
}
|
||||
canWrapX() {
|
||||
return this.canWrapX_;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Get the code for this projection, e.g. 'EPSG:4326'.
|
||||
* @return {string} Code.
|
||||
* @api
|
||||
*/
|
||||
getCode() {
|
||||
return this.code_;
|
||||
}
|
||||
getCode() {
|
||||
return this.code_;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Get the validity extent for this projection.
|
||||
* @return {module:ol/extent~Extent} Extent.
|
||||
* @api
|
||||
*/
|
||||
getExtent() {
|
||||
return this.extent_;
|
||||
}
|
||||
getExtent() {
|
||||
return this.extent_;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Get the units of this projection.
|
||||
* @return {module:ol/proj/Units} Units.
|
||||
* @api
|
||||
*/
|
||||
getUnits() {
|
||||
return this.units_;
|
||||
}
|
||||
getUnits() {
|
||||
return this.units_;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Get the amount of meters per unit of this projection. If the projection is
|
||||
* not configured with `metersPerUnit` or a units identifier, the return is
|
||||
* `undefined`.
|
||||
* @return {number|undefined} Meters.
|
||||
* @api
|
||||
*/
|
||||
getMetersPerUnit() {
|
||||
return this.metersPerUnit_ || METERS_PER_UNIT[this.units_];
|
||||
}
|
||||
getMetersPerUnit() {
|
||||
return this.metersPerUnit_ || METERS_PER_UNIT[this.units_];
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Get the world extent for this projection.
|
||||
* @return {module:ol/extent~Extent} Extent.
|
||||
* @api
|
||||
*/
|
||||
getWorldExtent() {
|
||||
return this.worldExtent_;
|
||||
}
|
||||
getWorldExtent() {
|
||||
return this.worldExtent_;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Get the axis orientation of this projection.
|
||||
* Example values are:
|
||||
* enu - the default easting, northing, elevation.
|
||||
@@ -193,81 +193,81 @@ class Projection {
|
||||
* @return {string} Axis orientation.
|
||||
* @api
|
||||
*/
|
||||
getAxisOrientation() {
|
||||
return this.axisOrientation_;
|
||||
}
|
||||
getAxisOrientation() {
|
||||
return this.axisOrientation_;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Is this projection a global projection which spans the whole world?
|
||||
* @return {boolean} Whether the projection is global.
|
||||
* @api
|
||||
*/
|
||||
isGlobal() {
|
||||
return this.global_;
|
||||
}
|
||||
isGlobal() {
|
||||
return this.global_;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Set if the projection is a global projection which spans the whole world
|
||||
* @param {boolean} global Whether the projection is global.
|
||||
* @api
|
||||
*/
|
||||
setGlobal(global) {
|
||||
this.global_ = global;
|
||||
this.canWrapX_ = !!(global && this.extent_);
|
||||
}
|
||||
setGlobal(global) {
|
||||
this.global_ = global;
|
||||
this.canWrapX_ = !!(global && this.extent_);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* @return {module:ol/tilegrid/TileGrid} The default tile grid.
|
||||
*/
|
||||
getDefaultTileGrid() {
|
||||
return this.defaultTileGrid_;
|
||||
}
|
||||
getDefaultTileGrid() {
|
||||
return this.defaultTileGrid_;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* @param {module:ol/tilegrid/TileGrid} tileGrid The default tile grid.
|
||||
*/
|
||||
setDefaultTileGrid(tileGrid) {
|
||||
this.defaultTileGrid_ = tileGrid;
|
||||
}
|
||||
setDefaultTileGrid(tileGrid) {
|
||||
this.defaultTileGrid_ = tileGrid;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Set the validity extent for this projection.
|
||||
* @param {module:ol/extent~Extent} extent Extent.
|
||||
* @api
|
||||
*/
|
||||
setExtent(extent) {
|
||||
this.extent_ = extent;
|
||||
this.canWrapX_ = !!(this.global_ && extent);
|
||||
}
|
||||
setExtent(extent) {
|
||||
this.extent_ = extent;
|
||||
this.canWrapX_ = !!(this.global_ && extent);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Set the world extent for this projection.
|
||||
* @param {module:ol/extent~Extent} worldExtent World extent
|
||||
* [minlon, minlat, maxlon, maxlat].
|
||||
* @api
|
||||
*/
|
||||
setWorldExtent(worldExtent) {
|
||||
this.worldExtent_ = worldExtent;
|
||||
}
|
||||
setWorldExtent(worldExtent) {
|
||||
this.worldExtent_ = worldExtent;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Set the getPointResolution function (see {@link module:ol/proj~getPointResolution}
|
||||
* for this projection.
|
||||
* @param {function(number, module:ol/coordinate~Coordinate):number} func Function
|
||||
* @api
|
||||
*/
|
||||
setGetPointResolution(func) {
|
||||
this.getPointResolutionFunc_ = func;
|
||||
}
|
||||
setGetPointResolution(func) {
|
||||
this.getPointResolutionFunc_ = func;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Get the custom point resolution function for this projection (if set).
|
||||
* @return {function(number, module:ol/coordinate~Coordinate):number|undefined} The custom point
|
||||
* resolution function (if set).
|
||||
*/
|
||||
getPointResolutionFunc() {
|
||||
return this.getPointResolutionFunc_;
|
||||
}
|
||||
getPointResolutionFunc() {
|
||||
return this.getPointResolutionFunc_;
|
||||
}
|
||||
}
|
||||
|
||||
export default Projection;
|
||||
|
||||
@@ -48,18 +48,24 @@ export const WORLD_EXTENT = [-180, -85, 180, 85];
|
||||
* @extends {module:ol/proj/Projection}
|
||||
* @param {string} code Code.
|
||||
*/
|
||||
function EPSG3857Projection(code) {
|
||||
Projection.call(this, {
|
||||
code: code,
|
||||
units: Units.METERS,
|
||||
extent: EXTENT,
|
||||
global: true,
|
||||
worldExtent: WORLD_EXTENT,
|
||||
getPointResolution: function(resolution, point) {
|
||||
return resolution / cosh(point[1] / RADIUS);
|
||||
}
|
||||
});
|
||||
class EPSG3857Projection {
|
||||
|
||||
constructor(code) {
|
||||
Projection.call(this, {
|
||||
code: code,
|
||||
units: Units.METERS,
|
||||
extent: EXTENT,
|
||||
global: true,
|
||||
worldExtent: WORLD_EXTENT,
|
||||
getPointResolution: function(resolution, point) {
|
||||
return resolution / cosh(point[1] / RADIUS);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inherits(EPSG3857Projection, Projection);
|
||||
|
||||
|
||||
|
||||
@@ -44,17 +44,23 @@ export const METERS_PER_UNIT = Math.PI * RADIUS / 180;
|
||||
* @param {string} code Code.
|
||||
* @param {string=} opt_axisOrientation Axis orientation.
|
||||
*/
|
||||
function EPSG4326Projection(code, opt_axisOrientation) {
|
||||
Projection.call(this, {
|
||||
code: code,
|
||||
units: Units.DEGREES,
|
||||
extent: EXTENT,
|
||||
axisOrientation: opt_axisOrientation,
|
||||
global: true,
|
||||
metersPerUnit: METERS_PER_UNIT,
|
||||
worldExtent: EXTENT
|
||||
});
|
||||
class EPSG4326Projection {
|
||||
|
||||
constructor(code, opt_axisOrientation) {
|
||||
Projection.call(this, {
|
||||
code: code,
|
||||
units: Units.DEGREES,
|
||||
extent: EXTENT,
|
||||
axisOrientation: opt_axisOrientation,
|
||||
global: true,
|
||||
metersPerUnit: METERS_PER_UNIT,
|
||||
worldExtent: EXTENT
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inherits(EPSG4326Projection, Projection);
|
||||
|
||||
|
||||
|
||||
@@ -13,43 +13,45 @@ import Event from '../events/Event.js';
|
||||
* @param {?CanvasRenderingContext2D=} opt_context Context.
|
||||
* @param {?module:ol/webgl/Context=} opt_glContext WebGL Context.
|
||||
*/
|
||||
const RenderEvent = function(
|
||||
type, opt_vectorContext, opt_frameState, opt_context,
|
||||
opt_glContext) {
|
||||
class RenderEvent {
|
||||
|
||||
Event.call(this, type);
|
||||
constructor(type, opt_vectorContext, opt_frameState, opt_context, opt_glContext) {
|
||||
|
||||
/**
|
||||
* For canvas, this is an instance of {@link module:ol/render/canvas/Immediate}.
|
||||
* @type {module:ol/render/VectorContext|undefined}
|
||||
* @api
|
||||
*/
|
||||
this.vectorContext = opt_vectorContext;
|
||||
Event.call(this, type);
|
||||
|
||||
/**
|
||||
* An object representing the current render frame state.
|
||||
* @type {module:ol/PluggableMap~FrameState|undefined}
|
||||
* @api
|
||||
*/
|
||||
this.frameState = opt_frameState;
|
||||
/**
|
||||
* For canvas, this is an instance of {@link module:ol/render/canvas/Immediate}.
|
||||
* @type {module:ol/render/VectorContext|undefined}
|
||||
* @api
|
||||
*/
|
||||
this.vectorContext = opt_vectorContext;
|
||||
|
||||
/**
|
||||
* Canvas context. Only available when a Canvas renderer is used, null
|
||||
* otherwise.
|
||||
* @type {CanvasRenderingContext2D|null|undefined}
|
||||
* @api
|
||||
*/
|
||||
this.context = opt_context;
|
||||
/**
|
||||
* An object representing the current render frame state.
|
||||
* @type {module:ol/PluggableMap~FrameState|undefined}
|
||||
* @api
|
||||
*/
|
||||
this.frameState = opt_frameState;
|
||||
|
||||
/**
|
||||
* WebGL context. Only available when a WebGL renderer is used, null
|
||||
* otherwise.
|
||||
* @type {module:ol/webgl/Context|null|undefined}
|
||||
* @api
|
||||
*/
|
||||
this.glContext = opt_glContext;
|
||||
/**
|
||||
* Canvas context. Only available when a Canvas renderer is used, null
|
||||
* otherwise.
|
||||
* @type {CanvasRenderingContext2D|null|undefined}
|
||||
* @api
|
||||
*/
|
||||
this.context = opt_context;
|
||||
|
||||
};
|
||||
/**
|
||||
* WebGL context. Only available when a WebGL renderer is used, null
|
||||
* otherwise.
|
||||
* @type {module:ol/webgl/Context|null|undefined}
|
||||
* @api
|
||||
*/
|
||||
this.glContext = opt_glContext;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inherits(RenderEvent, Event);
|
||||
export default RenderEvent;
|
||||
|
||||
@@ -12,79 +12,84 @@ import {DEBUG as DEBUG_WEBGL} from '../../../../webgl.js';
|
||||
* @param {WebGLProgram} program Program.
|
||||
* @struct
|
||||
*/
|
||||
const Locations = function(gl, program) {
|
||||
class Locations {
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_projectionMatrix = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_projectionMatrix' : 'h');
|
||||
constructor(gl, program) {
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_offsetScaleMatrix = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_offsetScaleMatrix' : 'i');
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_projectionMatrix = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_projectionMatrix' : 'h');
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_offsetRotateMatrix = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_offsetRotateMatrix' : 'j');
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_offsetScaleMatrix = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_offsetScaleMatrix' : 'i');
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_lineWidth = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_lineWidth' : 'k');
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_offsetRotateMatrix = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_offsetRotateMatrix' : 'j');
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_pixelRatio = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_pixelRatio' : 'l');
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_lineWidth = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_lineWidth' : 'k');
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_opacity = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_opacity' : 'm');
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_pixelRatio = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_pixelRatio' : 'l');
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_fillColor = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_fillColor' : 'n');
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_opacity = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_opacity' : 'm');
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_strokeColor = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_strokeColor' : 'o');
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_fillColor = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_fillColor' : 'n');
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_size = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_size' : 'p');
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_strokeColor = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_strokeColor' : 'o');
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_position = gl.getAttribLocation(
|
||||
program, DEBUG_WEBGL ? 'a_position' : 'e');
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_size = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_size' : 'p');
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_instruction = gl.getAttribLocation(
|
||||
program, DEBUG_WEBGL ? 'a_instruction' : 'f');
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_position = gl.getAttribLocation(
|
||||
program, DEBUG_WEBGL ? 'a_position' : 'e');
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_radius = gl.getAttribLocation(
|
||||
program, DEBUG_WEBGL ? 'a_radius' : 'g');
|
||||
};
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_instruction = gl.getAttribLocation(
|
||||
program, DEBUG_WEBGL ? 'a_instruction' : 'f');
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_radius = gl.getAttribLocation(
|
||||
program, DEBUG_WEBGL ? 'a_radius' : 'g');
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Locations;
|
||||
|
||||
@@ -12,85 +12,90 @@ import {DEBUG as DEBUG_WEBGL} from '../../../../webgl.js';
|
||||
* @param {WebGLProgram} program Program.
|
||||
* @struct
|
||||
*/
|
||||
const Locations = function(gl, program) {
|
||||
class Locations {
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_projectionMatrix = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_projectionMatrix' : 'h');
|
||||
constructor(gl, program) {
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_offsetScaleMatrix = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_offsetScaleMatrix' : 'i');
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_projectionMatrix = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_projectionMatrix' : 'h');
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_offsetRotateMatrix = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_offsetRotateMatrix' : 'j');
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_offsetScaleMatrix = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_offsetScaleMatrix' : 'i');
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_lineWidth = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_lineWidth' : 'k');
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_offsetRotateMatrix = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_offsetRotateMatrix' : 'j');
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_miterLimit = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_miterLimit' : 'l');
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_lineWidth = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_lineWidth' : 'k');
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_opacity = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_opacity' : 'm');
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_miterLimit = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_miterLimit' : 'l');
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_color = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_color' : 'n');
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_opacity = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_opacity' : 'm');
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_size = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_size' : 'o');
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_color = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_color' : 'n');
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_pixelRatio = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_pixelRatio' : 'p');
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_size = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_size' : 'o');
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_lastPos = gl.getAttribLocation(
|
||||
program, DEBUG_WEBGL ? 'a_lastPos' : 'd');
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_pixelRatio = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_pixelRatio' : 'p');
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_position = gl.getAttribLocation(
|
||||
program, DEBUG_WEBGL ? 'a_position' : 'e');
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_lastPos = gl.getAttribLocation(
|
||||
program, DEBUG_WEBGL ? 'a_lastPos' : 'd');
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_nextPos = gl.getAttribLocation(
|
||||
program, DEBUG_WEBGL ? 'a_nextPos' : 'f');
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_position = gl.getAttribLocation(
|
||||
program, DEBUG_WEBGL ? 'a_position' : 'e');
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_direction = gl.getAttribLocation(
|
||||
program, DEBUG_WEBGL ? 'a_direction' : 'g');
|
||||
};
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_nextPos = gl.getAttribLocation(
|
||||
program, DEBUG_WEBGL ? 'a_nextPos' : 'f');
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_direction = gl.getAttribLocation(
|
||||
program, DEBUG_WEBGL ? 'a_direction' : 'g');
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Locations;
|
||||
|
||||
@@ -12,43 +12,48 @@ import {DEBUG as DEBUG_WEBGL} from '../../../../webgl.js';
|
||||
* @param {WebGLProgram} program Program.
|
||||
* @struct
|
||||
*/
|
||||
const Locations = function(gl, program) {
|
||||
class Locations {
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_projectionMatrix = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_projectionMatrix' : 'b');
|
||||
constructor(gl, program) {
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_offsetScaleMatrix = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_offsetScaleMatrix' : 'c');
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_projectionMatrix = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_projectionMatrix' : 'b');
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_offsetRotateMatrix = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_offsetRotateMatrix' : 'd');
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_offsetScaleMatrix = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_offsetScaleMatrix' : 'c');
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_color = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_color' : 'e');
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_offsetRotateMatrix = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_offsetRotateMatrix' : 'd');
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_opacity = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_opacity' : 'f');
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_color = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_color' : 'e');
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_position = gl.getAttribLocation(
|
||||
program, DEBUG_WEBGL ? 'a_position' : 'a');
|
||||
};
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_opacity = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_opacity' : 'f');
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_position = gl.getAttribLocation(
|
||||
program, DEBUG_WEBGL ? 'a_position' : 'a');
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Locations;
|
||||
|
||||
@@ -12,67 +12,72 @@ import {DEBUG as DEBUG_WEBGL} from '../../../../webgl.js';
|
||||
* @param {WebGLProgram} program Program.
|
||||
* @struct
|
||||
*/
|
||||
const Locations = function(gl, program) {
|
||||
class Locations {
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_projectionMatrix = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_projectionMatrix' : 'h');
|
||||
constructor(gl, program) {
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_offsetScaleMatrix = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_offsetScaleMatrix' : 'i');
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_projectionMatrix = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_projectionMatrix' : 'h');
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_offsetRotateMatrix = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_offsetRotateMatrix' : 'j');
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_offsetScaleMatrix = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_offsetScaleMatrix' : 'i');
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_opacity = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_opacity' : 'k');
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_offsetRotateMatrix = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_offsetRotateMatrix' : 'j');
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_image = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_image' : 'l');
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_opacity = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_opacity' : 'k');
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_position = gl.getAttribLocation(
|
||||
program, DEBUG_WEBGL ? 'a_position' : 'c');
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_image = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_image' : 'l');
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_texCoord = gl.getAttribLocation(
|
||||
program, DEBUG_WEBGL ? 'a_texCoord' : 'd');
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_position = gl.getAttribLocation(
|
||||
program, DEBUG_WEBGL ? 'a_position' : 'c');
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_offsets = gl.getAttribLocation(
|
||||
program, DEBUG_WEBGL ? 'a_offsets' : 'e');
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_texCoord = gl.getAttribLocation(
|
||||
program, DEBUG_WEBGL ? 'a_texCoord' : 'd');
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_opacity = gl.getAttribLocation(
|
||||
program, DEBUG_WEBGL ? 'a_opacity' : 'f');
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_offsets = gl.getAttribLocation(
|
||||
program, DEBUG_WEBGL ? 'a_offsets' : 'e');
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_rotateWithView = gl.getAttribLocation(
|
||||
program, DEBUG_WEBGL ? 'a_rotateWithView' : 'g');
|
||||
};
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_opacity = gl.getAttribLocation(
|
||||
program, DEBUG_WEBGL ? 'a_opacity' : 'f');
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_rotateWithView = gl.getAttribLocation(
|
||||
program, DEBUG_WEBGL ? 'a_rotateWithView' : 'g');
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Locations;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// This file is automatically generated, do not edit
|
||||
// Run `make shaders` to generate, and commit the result.
|
||||
|
||||
import {DEBUG as DEBUG_WEBGL} from '../../../webgl.js';
|
||||
import {DEBUG as DEBUG_WEBGL} from '../../../../webgl.js';
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
@@ -12,43 +12,48 @@ import {DEBUG as DEBUG_WEBGL} from '../../../webgl.js';
|
||||
* @param {WebGLProgram} program Program.
|
||||
* @struct
|
||||
*/
|
||||
const Locations = function(gl, program) {
|
||||
class Locations {
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_texCoordMatrix = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_texCoordMatrix' : 'd');
|
||||
constructor(gl, program) {
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_projectionMatrix = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_projectionMatrix' : 'e');
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_texCoordMatrix = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_texCoordMatrix' : 'd');
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_opacity = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_opacity' : 'f');
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_projectionMatrix = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_projectionMatrix' : 'e');
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_texture = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_texture' : 'g');
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_opacity = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_opacity' : 'f');
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_position = gl.getAttribLocation(
|
||||
program, DEBUG_WEBGL ? 'a_position' : 'b');
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_texture = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_texture' : 'g');
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_texCoord = gl.getAttribLocation(
|
||||
program, DEBUG_WEBGL ? 'a_texCoord' : 'c');
|
||||
};
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_position = gl.getAttribLocation(
|
||||
program, DEBUG_WEBGL ? 'a_position' : 'b');
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_texCoord = gl.getAttribLocation(
|
||||
program, DEBUG_WEBGL ? 'a_texCoord' : 'c');
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Locations;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// This file is automatically generated, do not edit
|
||||
// Run `make shaders` to generate, and commit the result.
|
||||
|
||||
import {DEBUG as DEBUG_WEBGL} from '../../../webgl.js';
|
||||
import {DEBUG as DEBUG_WEBGL} from '../../../../webgl.js';
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
@@ -12,31 +12,36 @@ import {DEBUG as DEBUG_WEBGL} from '../../../webgl.js';
|
||||
* @param {WebGLProgram} program Program.
|
||||
* @struct
|
||||
*/
|
||||
const Locations = function(gl, program) {
|
||||
class Locations {
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_tileOffset = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_tileOffset' : 'd');
|
||||
constructor(gl, program) {
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_texture = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_texture' : 'e');
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_tileOffset = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_tileOffset' : 'd');
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_position = gl.getAttribLocation(
|
||||
program, DEBUG_WEBGL ? 'a_position' : 'b');
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_texture = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? 'u_texture' : 'e');
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_texCoord = gl.getAttribLocation(
|
||||
program, DEBUG_WEBGL ? 'a_texCoord' : 'c');
|
||||
};
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_position = gl.getAttribLocation(
|
||||
program, DEBUG_WEBGL ? 'a_position' : 'b');
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_texCoord = gl.getAttribLocation(
|
||||
program, DEBUG_WEBGL ? 'a_texCoord' : 'c');
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Locations;
|
||||
|
||||
@@ -51,18 +51,23 @@ const ImageSourceEventType = {
|
||||
* @param {string} type Type.
|
||||
* @param {module:ol/Image} image The image.
|
||||
*/
|
||||
const ImageSourceEvent = function(type, image) {
|
||||
class ImageSourceEvent {
|
||||
|
||||
Event.call(this, type);
|
||||
constructor(type, image) {
|
||||
|
||||
/**
|
||||
* The image related to the event.
|
||||
* @type {module:ol/Image}
|
||||
* @api
|
||||
*/
|
||||
this.image = image;
|
||||
Event.call(this, type);
|
||||
|
||||
/**
|
||||
* The image related to the event.
|
||||
* @type {module:ol/Image}
|
||||
* @api
|
||||
*/
|
||||
this.image = image;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
inherits(ImageSourceEvent, Event);
|
||||
|
||||
|
||||
|
||||
@@ -50,36 +50,40 @@ export const ATTRIBUTION = '© ' +
|
||||
* @param {module:ol/source/OSM~Options=} [opt_options] Open Street Map options.
|
||||
* @api
|
||||
*/
|
||||
const OSM = function(opt_options) {
|
||||
class OSM {
|
||||
|
||||
const options = opt_options || {};
|
||||
constructor(opt_options) {
|
||||
|
||||
const options = opt_options || {};
|
||||
|
||||
let attributions;
|
||||
if (options.attributions !== undefined) {
|
||||
attributions = options.attributions;
|
||||
} else {
|
||||
attributions = [ATTRIBUTION];
|
||||
}
|
||||
|
||||
const crossOrigin = options.crossOrigin !== undefined ?
|
||||
options.crossOrigin : 'anonymous';
|
||||
|
||||
const url = options.url !== undefined ?
|
||||
options.url : 'https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png';
|
||||
|
||||
XYZ.call(this, {
|
||||
attributions: attributions,
|
||||
cacheSize: options.cacheSize,
|
||||
crossOrigin: crossOrigin,
|
||||
opaque: options.opaque !== undefined ? options.opaque : true,
|
||||
maxZoom: options.maxZoom !== undefined ? options.maxZoom : 19,
|
||||
reprojectionErrorThreshold: options.reprojectionErrorThreshold,
|
||||
tileLoadFunction: options.tileLoadFunction,
|
||||
url: url,
|
||||
wrapX: options.wrapX
|
||||
});
|
||||
|
||||
let attributions;
|
||||
if (options.attributions !== undefined) {
|
||||
attributions = options.attributions;
|
||||
} else {
|
||||
attributions = [ATTRIBUTION];
|
||||
}
|
||||
|
||||
const crossOrigin = options.crossOrigin !== undefined ?
|
||||
options.crossOrigin : 'anonymous';
|
||||
|
||||
const url = options.url !== undefined ?
|
||||
options.url : 'https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png';
|
||||
|
||||
XYZ.call(this, {
|
||||
attributions: attributions,
|
||||
cacheSize: options.cacheSize,
|
||||
crossOrigin: crossOrigin,
|
||||
opaque: options.opaque !== undefined ? options.opaque : true,
|
||||
maxZoom: options.maxZoom !== undefined ? options.maxZoom : 19,
|
||||
reprojectionErrorThreshold: options.reprojectionErrorThreshold,
|
||||
tileLoadFunction: options.tileLoadFunction,
|
||||
url: url,
|
||||
wrapX: options.wrapX
|
||||
});
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
inherits(OSM, XYZ);
|
||||
|
||||
|
||||
@@ -83,32 +83,37 @@ const RasterOperationType = {
|
||||
* @param {module:ol/PluggableMap~FrameState} frameState The frame state.
|
||||
* @param {Object} data An object made available to operations.
|
||||
*/
|
||||
const RasterSourceEvent = function(type, frameState, data) {
|
||||
Event.call(this, type);
|
||||
class RasterSourceEvent {
|
||||
|
||||
/**
|
||||
* The raster extent.
|
||||
* @type {module:ol/extent~Extent}
|
||||
* @api
|
||||
*/
|
||||
this.extent = frameState.extent;
|
||||
constructor(type, frameState, data) {
|
||||
Event.call(this, type);
|
||||
|
||||
/**
|
||||
* The pixel resolution (map units per pixel).
|
||||
* @type {number}
|
||||
* @api
|
||||
*/
|
||||
this.resolution = frameState.viewState.resolution / frameState.pixelRatio;
|
||||
/**
|
||||
* The raster extent.
|
||||
* @type {module:ol/extent~Extent}
|
||||
* @api
|
||||
*/
|
||||
this.extent = frameState.extent;
|
||||
|
||||
/**
|
||||
* An object made available to all operations. This can be used by operations
|
||||
* as a storage object (e.g. for calculating statistics).
|
||||
* @type {Object}
|
||||
* @api
|
||||
*/
|
||||
this.data = data;
|
||||
/**
|
||||
* The pixel resolution (map units per pixel).
|
||||
* @type {number}
|
||||
* @api
|
||||
*/
|
||||
this.resolution = frameState.viewState.resolution / frameState.pixelRatio;
|
||||
|
||||
/**
|
||||
* An object made available to all operations. This can be used by operations
|
||||
* as a storage object (e.g. for calculating statistics).
|
||||
* @type {Object}
|
||||
* @api
|
||||
*/
|
||||
this.data = data;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
inherits(RasterSourceEvent, Event);
|
||||
|
||||
/**
|
||||
|
||||
@@ -118,30 +118,35 @@ const ProviderConfig = {
|
||||
* @param {module:ol/source/Stamen~Options=} options Stamen options.
|
||||
* @api
|
||||
*/
|
||||
const Stamen = function(options) {
|
||||
const i = options.layer.indexOf('-');
|
||||
const provider = i == -1 ? options.layer : options.layer.slice(0, i);
|
||||
const providerConfig = ProviderConfig[provider];
|
||||
class Stamen {
|
||||
|
||||
const layerConfig = LayerConfig[options.layer];
|
||||
constructor(options) {
|
||||
const i = options.layer.indexOf('-');
|
||||
const provider = i == -1 ? options.layer : options.layer.slice(0, i);
|
||||
const providerConfig = ProviderConfig[provider];
|
||||
|
||||
const url = options.url !== undefined ? options.url :
|
||||
'https://stamen-tiles-{a-d}.a.ssl.fastly.net/' + options.layer +
|
||||
'/{z}/{x}/{y}.' + layerConfig.extension;
|
||||
const layerConfig = LayerConfig[options.layer];
|
||||
|
||||
XYZ.call(this, {
|
||||
attributions: ATTRIBUTIONS,
|
||||
cacheSize: options.cacheSize,
|
||||
crossOrigin: 'anonymous',
|
||||
maxZoom: options.maxZoom != undefined ? options.maxZoom : providerConfig.maxZoom,
|
||||
minZoom: options.minZoom != undefined ? options.minZoom : providerConfig.minZoom,
|
||||
opaque: layerConfig.opaque,
|
||||
reprojectionErrorThreshold: options.reprojectionErrorThreshold,
|
||||
tileLoadFunction: options.tileLoadFunction,
|
||||
url: url,
|
||||
wrapX: options.wrapX
|
||||
});
|
||||
};
|
||||
const url = options.url !== undefined ? options.url :
|
||||
'https://stamen-tiles-{a-d}.a.ssl.fastly.net/' + options.layer +
|
||||
'/{z}/{x}/{y}.' + layerConfig.extension;
|
||||
|
||||
XYZ.call(this, {
|
||||
attributions: ATTRIBUTIONS,
|
||||
cacheSize: options.cacheSize,
|
||||
crossOrigin: 'anonymous',
|
||||
maxZoom: options.maxZoom != undefined ? options.maxZoom : providerConfig.maxZoom,
|
||||
minZoom: options.minZoom != undefined ? options.minZoom : providerConfig.minZoom,
|
||||
opaque: layerConfig.opaque,
|
||||
reprojectionErrorThreshold: options.reprojectionErrorThreshold,
|
||||
tileLoadFunction: options.tileLoadFunction,
|
||||
url: url,
|
||||
wrapX: options.wrapX
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inherits(Stamen, XYZ);
|
||||
|
||||
|
||||
@@ -318,18 +318,23 @@ TileSource.prototype.useTile = UNDEFINED;
|
||||
* @param {string} type Type.
|
||||
* @param {module:ol/Tile} tile The tile.
|
||||
*/
|
||||
export const TileSourceEvent = function(type, tile) {
|
||||
export class TileSourceEvent {
|
||||
|
||||
Event.call(this, type);
|
||||
constructor(type, tile) {
|
||||
|
||||
/**
|
||||
* The tile related to the event.
|
||||
* @type {module:ol/Tile}
|
||||
* @api
|
||||
*/
|
||||
this.tile = tile;
|
||||
Event.call(this, type);
|
||||
|
||||
/**
|
||||
* The tile related to the event.
|
||||
* @type {module:ol/Tile}
|
||||
* @api
|
||||
*/
|
||||
this.tile = tile;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
inherits(TileSourceEvent, Event);
|
||||
|
||||
export default TileSource;
|
||||
|
||||
@@ -27,54 +27,59 @@ import {createXYZ, extentFromProjection} from '../tilegrid.js';
|
||||
* @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) {
|
||||
export class CustomTile {
|
||||
|
||||
Tile.call(this, tileCoord, state);
|
||||
constructor(tileCoord, state, src, extent, preemptive, jsonp) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {string}
|
||||
*/
|
||||
this.src_ = src;
|
||||
Tile.call(this, tileCoord, state);
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/extent~Extent}
|
||||
*/
|
||||
this.extent_ = extent;
|
||||
/**
|
||||
* @private
|
||||
* @type {string}
|
||||
*/
|
||||
this.src_ = src;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.preemptive_ = preemptive;
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/extent~Extent}
|
||||
*/
|
||||
this.extent_ = extent;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<string>}
|
||||
*/
|
||||
this.grid_ = null;
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.preemptive_ = preemptive;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<string>}
|
||||
*/
|
||||
this.keys_ = null;
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<string>}
|
||||
*/
|
||||
this.grid_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Object.<string, Object>|undefined}
|
||||
*/
|
||||
this.data_ = null;
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<string>}
|
||||
*/
|
||||
this.keys_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Object.<string, Object>|undefined}
|
||||
*/
|
||||
this.data_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.jsonp_ = jsonp;
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.jsonp_ = jsonp;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
inherits(CustomTile, Tile);
|
||||
|
||||
|
||||
@@ -275,54 +280,59 @@ CustomTile.prototype.load = function() {
|
||||
* @param {module:ol/source/UTFGrid~Options=} options Source options.
|
||||
* @api
|
||||
*/
|
||||
const UTFGrid = function(options) {
|
||||
TileSource.call(this, {
|
||||
projection: getProjection('EPSG:3857'),
|
||||
state: SourceState.LOADING
|
||||
});
|
||||
class UTFGrid {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.preemptive_ = options.preemptive !== undefined ?
|
||||
options.preemptive : true;
|
||||
constructor(options) {
|
||||
TileSource.call(this, {
|
||||
projection: getProjection('EPSG:3857'),
|
||||
state: SourceState.LOADING
|
||||
});
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {!module:ol/Tile~UrlFunction}
|
||||
*/
|
||||
this.tileUrlFunction_ = nullTileUrlFunction;
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.preemptive_ = options.preemptive !== undefined ?
|
||||
options.preemptive : true;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {string|undefined}
|
||||
*/
|
||||
this.template_ = undefined;
|
||||
/**
|
||||
* @private
|
||||
* @type {!module:ol/Tile~UrlFunction}
|
||||
*/
|
||||
this.tileUrlFunction_ = nullTileUrlFunction;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.jsonp_ = options.jsonp || false;
|
||||
/**
|
||||
* @private
|
||||
* @type {string|undefined}
|
||||
*/
|
||||
this.template_ = undefined;
|
||||
|
||||
if (options.url) {
|
||||
if (this.jsonp_) {
|
||||
requestJSONP(options.url, this.handleTileJSONResponse.bind(this),
|
||||
this.handleTileJSONError.bind(this));
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.jsonp_ = options.jsonp || false;
|
||||
|
||||
if (options.url) {
|
||||
if (this.jsonp_) {
|
||||
requestJSONP(options.url, this.handleTileJSONResponse.bind(this),
|
||||
this.handleTileJSONError.bind(this));
|
||||
} else {
|
||||
const client = new XMLHttpRequest();
|
||||
client.addEventListener('load', this.onXHRLoad_.bind(this));
|
||||
client.addEventListener('error', this.onXHRError_.bind(this));
|
||||
client.open('GET', options.url);
|
||||
client.send();
|
||||
}
|
||||
} else if (options.tileJSON) {
|
||||
this.handleTileJSONResponse(options.tileJSON);
|
||||
} else {
|
||||
const client = new XMLHttpRequest();
|
||||
client.addEventListener('load', this.onXHRLoad_.bind(this));
|
||||
client.addEventListener('error', this.onXHRError_.bind(this));
|
||||
client.open('GET', options.url);
|
||||
client.send();
|
||||
assert(false, 51); // Either `url` or `tileJSON` options must be provided
|
||||
}
|
||||
} else if (options.tileJSON) {
|
||||
this.handleTileJSONResponse(options.tileJSON);
|
||||
} else {
|
||||
assert(false, 51); // Either `url` or `tileJSON` options must be provided
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
inherits(UTFGrid, TileSource);
|
||||
|
||||
|
||||
@@ -41,18 +41,23 @@ import RBush from '../structs/RBush.js';
|
||||
* @param {string} type Type.
|
||||
* @param {module:ol/Feature=} opt_feature Feature.
|
||||
*/
|
||||
export const VectorSourceEvent = function(type, opt_feature) {
|
||||
export class VectorSourceEvent {
|
||||
|
||||
Event.call(this, type);
|
||||
constructor(type, opt_feature) {
|
||||
|
||||
/**
|
||||
* The feature being added or removed.
|
||||
* @type {module:ol/Feature|undefined}
|
||||
* @api
|
||||
*/
|
||||
this.feature = opt_feature;
|
||||
Event.call(this, type);
|
||||
|
||||
/**
|
||||
* The feature being added or removed.
|
||||
* @type {module:ol/Feature|undefined}
|
||||
* @api
|
||||
*/
|
||||
this.feature = opt_feature;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
inherits(VectorSourceEvent, Event);
|
||||
|
||||
|
||||
@@ -158,120 +163,124 @@ inherits(VectorSourceEvent, Event);
|
||||
* @param {module:ol/source/Vector~Options=} opt_options Vector source options.
|
||||
* @api
|
||||
*/
|
||||
const VectorSource = function(opt_options) {
|
||||
class VectorSource {
|
||||
|
||||
const options = opt_options || {};
|
||||
constructor(opt_options) {
|
||||
|
||||
Source.call(this, {
|
||||
attributions: options.attributions,
|
||||
projection: undefined,
|
||||
state: SourceState.READY,
|
||||
wrapX: options.wrapX !== undefined ? options.wrapX : true
|
||||
});
|
||||
const options = opt_options || {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/featureloader~FeatureLoader}
|
||||
*/
|
||||
this.loader_ = UNDEFINED;
|
||||
Source.call(this, {
|
||||
attributions: options.attributions,
|
||||
projection: undefined,
|
||||
state: SourceState.READY,
|
||||
wrapX: options.wrapX !== undefined ? options.wrapX : true
|
||||
});
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/format/Feature|undefined}
|
||||
*/
|
||||
this.format_ = options.format;
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/featureloader~FeatureLoader}
|
||||
*/
|
||||
this.loader_ = UNDEFINED;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.overlaps_ = options.overlaps == undefined ? true : options.overlaps;
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/format/Feature|undefined}
|
||||
*/
|
||||
this.format_ = options.format;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {string|module:ol/featureloader~FeatureUrlFunction|undefined}
|
||||
*/
|
||||
this.url_ = options.url;
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.overlaps_ = options.overlaps == undefined ? true : options.overlaps;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {string|module:ol/featureloader~FeatureUrlFunction|undefined}
|
||||
*/
|
||||
this.url_ = options.url;
|
||||
|
||||
if (options.loader !== undefined) {
|
||||
this.loader_ = options.loader;
|
||||
} else if (this.url_ !== undefined) {
|
||||
assert(this.format_, 7); // `format` must be set when `url` is set
|
||||
// create a XHR feature loader for "url" and "format"
|
||||
this.loader_ = xhr(this.url_, /** @type {module:ol/format/Feature} */ (this.format_));
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/source/Vector~LoadingStrategy}
|
||||
*/
|
||||
this.strategy_ = options.strategy !== undefined ? options.strategy : allStrategy;
|
||||
|
||||
const useSpatialIndex =
|
||||
options.useSpatialIndex !== undefined ? options.useSpatialIndex : true;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/structs/RBush.<module:ol/Feature>}
|
||||
*/
|
||||
this.featuresRtree_ = useSpatialIndex ? new RBush() : null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/structs/RBush.<{extent: module:ol/extent~Extent}>}
|
||||
*/
|
||||
this.loadedExtentsRtree_ = new RBush();
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {!Object.<string, module:ol/Feature>}
|
||||
*/
|
||||
this.nullGeometryFeatures_ = {};
|
||||
|
||||
/**
|
||||
* A lookup of features by id (the return from feature.getId()).
|
||||
* @private
|
||||
* @type {!Object.<string, module:ol/Feature>}
|
||||
*/
|
||||
this.idIndex_ = {};
|
||||
|
||||
/**
|
||||
* A lookup of features without id (keyed by getUid(feature)).
|
||||
* @private
|
||||
* @type {!Object.<string, module:ol/Feature>}
|
||||
*/
|
||||
this.undefIdIndex_ = {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Object.<string, Array.<module:ol/events~EventsKey>>}
|
||||
*/
|
||||
this.featureChangeKeys_ = {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/Collection.<module:ol/Feature>}
|
||||
*/
|
||||
this.featuresCollection_ = null;
|
||||
|
||||
let collection, features;
|
||||
if (options.features instanceof Collection) {
|
||||
collection = options.features;
|
||||
features = collection.getArray();
|
||||
} else if (Array.isArray(options.features)) {
|
||||
features = options.features;
|
||||
}
|
||||
if (!useSpatialIndex && collection === undefined) {
|
||||
collection = new Collection(features);
|
||||
}
|
||||
if (features !== undefined) {
|
||||
this.addFeaturesInternal(features);
|
||||
}
|
||||
if (collection !== undefined) {
|
||||
this.bindFeaturesCollection_(collection);
|
||||
}
|
||||
|
||||
if (options.loader !== undefined) {
|
||||
this.loader_ = options.loader;
|
||||
} else if (this.url_ !== undefined) {
|
||||
assert(this.format_, 7); // `format` must be set when `url` is set
|
||||
// create a XHR feature loader for "url" and "format"
|
||||
this.loader_ = xhr(this.url_, /** @type {module:ol/format/Feature} */ (this.format_));
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/source/Vector~LoadingStrategy}
|
||||
*/
|
||||
this.strategy_ = options.strategy !== undefined ? options.strategy : allStrategy;
|
||||
|
||||
const useSpatialIndex =
|
||||
options.useSpatialIndex !== undefined ? options.useSpatialIndex : true;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/structs/RBush.<module:ol/Feature>}
|
||||
*/
|
||||
this.featuresRtree_ = useSpatialIndex ? new RBush() : null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/structs/RBush.<{extent: module:ol/extent~Extent}>}
|
||||
*/
|
||||
this.loadedExtentsRtree_ = new RBush();
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {!Object.<string, module:ol/Feature>}
|
||||
*/
|
||||
this.nullGeometryFeatures_ = {};
|
||||
|
||||
/**
|
||||
* A lookup of features by id (the return from feature.getId()).
|
||||
* @private
|
||||
* @type {!Object.<string, module:ol/Feature>}
|
||||
*/
|
||||
this.idIndex_ = {};
|
||||
|
||||
/**
|
||||
* A lookup of features without id (keyed by getUid(feature)).
|
||||
* @private
|
||||
* @type {!Object.<string, module:ol/Feature>}
|
||||
*/
|
||||
this.undefIdIndex_ = {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Object.<string, Array.<module:ol/events~EventsKey>>}
|
||||
*/
|
||||
this.featureChangeKeys_ = {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/Collection.<module:ol/Feature>}
|
||||
*/
|
||||
this.featuresCollection_ = null;
|
||||
|
||||
let collection, features;
|
||||
if (options.features instanceof Collection) {
|
||||
collection = options.features;
|
||||
features = collection.getArray();
|
||||
} else if (Array.isArray(options.features)) {
|
||||
features = options.features;
|
||||
}
|
||||
if (!useSpatialIndex && collection === undefined) {
|
||||
collection = new Collection(features);
|
||||
}
|
||||
if (features !== undefined) {
|
||||
this.addFeaturesInternal(features);
|
||||
}
|
||||
if (collection !== undefined) {
|
||||
this.bindFeaturesCollection_(collection);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
inherits(VectorSource, Source);
|
||||
|
||||
|
||||
@@ -74,66 +74,70 @@ import {createXYZ, extentFromProjection, createForProjection} from '../tilegrid.
|
||||
* @param {module:ol/source/VectorTile~Options=} options Vector tile options.
|
||||
* @api
|
||||
*/
|
||||
const VectorTile = function(options) {
|
||||
const projection = options.projection || 'EPSG:3857';
|
||||
class VectorTile {
|
||||
|
||||
const extent = options.extent || extentFromProjection(projection);
|
||||
constructor(options) {
|
||||
const projection = options.projection || 'EPSG:3857';
|
||||
|
||||
const tileGrid = options.tileGrid || createXYZ({
|
||||
extent: extent,
|
||||
maxZoom: options.maxZoom || 22,
|
||||
minZoom: options.minZoom,
|
||||
tileSize: options.tileSize || 512
|
||||
});
|
||||
const extent = options.extent || extentFromProjection(projection);
|
||||
|
||||
UrlTile.call(this, {
|
||||
attributions: options.attributions,
|
||||
cacheSize: options.cacheSize !== undefined ? options.cacheSize : 128,
|
||||
extent: extent,
|
||||
opaque: false,
|
||||
projection: projection,
|
||||
state: options.state,
|
||||
tileGrid: tileGrid,
|
||||
tileLoadFunction: options.tileLoadFunction ? options.tileLoadFunction : defaultLoadFunction,
|
||||
tileUrlFunction: options.tileUrlFunction,
|
||||
url: options.url,
|
||||
urls: options.urls,
|
||||
wrapX: options.wrapX === undefined ? true : options.wrapX,
|
||||
transition: options.transition
|
||||
});
|
||||
const tileGrid = options.tileGrid || createXYZ({
|
||||
extent: extent,
|
||||
maxZoom: options.maxZoom || 22,
|
||||
minZoom: options.minZoom,
|
||||
tileSize: options.tileSize || 512
|
||||
});
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/format/Feature}
|
||||
*/
|
||||
this.format_ = options.format ? options.format : null;
|
||||
UrlTile.call(this, {
|
||||
attributions: options.attributions,
|
||||
cacheSize: options.cacheSize !== undefined ? options.cacheSize : 128,
|
||||
extent: extent,
|
||||
opaque: false,
|
||||
projection: projection,
|
||||
state: options.state,
|
||||
tileGrid: tileGrid,
|
||||
tileLoadFunction: options.tileLoadFunction ? options.tileLoadFunction : defaultLoadFunction,
|
||||
tileUrlFunction: options.tileUrlFunction,
|
||||
url: options.url,
|
||||
urls: options.urls,
|
||||
wrapX: options.wrapX === undefined ? true : options.wrapX,
|
||||
transition: options.transition
|
||||
});
|
||||
|
||||
/**
|
||||
/**
|
||||
* @private
|
||||
* @type {Object.<string, module:ol/VectorTile>}
|
||||
* @type {module:ol/format/Feature}
|
||||
*/
|
||||
this.sourceTiles_ = {};
|
||||
this.format_ = options.format ? options.format : null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.overlaps_ = options.overlaps == undefined ? true : options.overlaps;
|
||||
/**
|
||||
* @private
|
||||
* @type {Object.<string, module:ol/VectorTile>}
|
||||
*/
|
||||
this.sourceTiles_ = {};
|
||||
|
||||
/**
|
||||
* @protected
|
||||
* @type {function(new: module:ol/VectorTile, module:ol/tilecoord~TileCoord, module:ol/TileState, string,
|
||||
* module:ol/format/Feature, module:ol/Tile~LoadFunction)}
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.tileClass = options.tileClass ? options.tileClass : Tile;
|
||||
this.overlaps_ = options.overlaps == undefined ? true : options.overlaps;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Object.<string, module:ol/tilegrid/TileGrid>}
|
||||
*/
|
||||
this.tileGrids_ = {};
|
||||
/**
|
||||
* @protected
|
||||
* @type {function(new: module:ol/VectorTile, module:ol/tilecoord~TileCoord, module:ol/TileState, string,
|
||||
* module:ol/format/Feature, module:ol/Tile~LoadFunction)}
|
||||
*/
|
||||
this.tileClass = options.tileClass ? options.tileClass : Tile;
|
||||
|
||||
};
|
||||
/**
|
||||
* @private
|
||||
* @type {Object.<string, module:ol/tilegrid/TileGrid>}
|
||||
*/
|
||||
this.tileGrids_ = {};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inherits(VectorTile, UrlTile);
|
||||
|
||||
|
||||
@@ -65,157 +65,161 @@ import {appendParams} from '../uri.js';
|
||||
* @param {module:ol/source/WMTS~Options=} options WMTS options.
|
||||
* @api
|
||||
*/
|
||||
const WMTS = function(options) {
|
||||
class WMTS {
|
||||
|
||||
// TODO: add support for TileMatrixLimits
|
||||
constructor(options) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {string}
|
||||
*/
|
||||
this.version_ = options.version !== undefined ? options.version : '1.0.0';
|
||||
// TODO: add support for TileMatrixLimits
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {string}
|
||||
*/
|
||||
this.format_ = options.format !== undefined ? options.format : 'image/jpeg';
|
||||
/**
|
||||
* @private
|
||||
* @type {string}
|
||||
*/
|
||||
this.version_ = options.version !== undefined ? options.version : '1.0.0';
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {!Object}
|
||||
*/
|
||||
this.dimensions_ = options.dimensions !== undefined ? options.dimensions : {};
|
||||
/**
|
||||
* @private
|
||||
* @type {string}
|
||||
*/
|
||||
this.format_ = options.format !== undefined ? options.format : 'image/jpeg';
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {string}
|
||||
*/
|
||||
this.layer_ = options.layer;
|
||||
/**
|
||||
* @private
|
||||
* @type {!Object}
|
||||
*/
|
||||
this.dimensions_ = options.dimensions !== undefined ? options.dimensions : {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {string}
|
||||
*/
|
||||
this.matrixSet_ = options.matrixSet;
|
||||
/**
|
||||
* @private
|
||||
* @type {string}
|
||||
*/
|
||||
this.layer_ = options.layer;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {string}
|
||||
*/
|
||||
this.style_ = options.style;
|
||||
/**
|
||||
* @private
|
||||
* @type {string}
|
||||
*/
|
||||
this.matrixSet_ = options.matrixSet;
|
||||
|
||||
let urls = options.urls;
|
||||
if (urls === undefined && options.url !== undefined) {
|
||||
urls = expandUrl(options.url);
|
||||
}
|
||||
/**
|
||||
* @private
|
||||
* @type {string}
|
||||
*/
|
||||
this.style_ = options.style;
|
||||
|
||||
// FIXME: should we guess this requestEncoding from options.url(s)
|
||||
// structure? that would mean KVP only if a template is not provided.
|
||||
let urls = options.urls;
|
||||
if (urls === undefined && options.url !== undefined) {
|
||||
urls = expandUrl(options.url);
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/source/WMTSRequestEncoding}
|
||||
*/
|
||||
this.requestEncoding_ = options.requestEncoding !== undefined ?
|
||||
/** @type {module:ol/source/WMTSRequestEncoding} */ (options.requestEncoding) :
|
||||
WMTSRequestEncoding.KVP;
|
||||
// FIXME: should we guess this requestEncoding from options.url(s)
|
||||
// structure? that would mean KVP only if a template is not provided.
|
||||
|
||||
const requestEncoding = this.requestEncoding_;
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/source/WMTSRequestEncoding}
|
||||
*/
|
||||
this.requestEncoding_ = options.requestEncoding !== undefined ?
|
||||
/** @type {module:ol/source/WMTSRequestEncoding} */ (options.requestEncoding) :
|
||||
WMTSRequestEncoding.KVP;
|
||||
|
||||
// FIXME: should we create a default tileGrid?
|
||||
// we could issue a getCapabilities xhr to retrieve missing configuration
|
||||
const tileGrid = options.tileGrid;
|
||||
const requestEncoding = this.requestEncoding_;
|
||||
|
||||
// context property names are lower case to allow for a case insensitive
|
||||
// replacement as some services use different naming conventions
|
||||
const context = {
|
||||
'layer': this.layer_,
|
||||
'style': this.style_,
|
||||
'tilematrixset': this.matrixSet_
|
||||
};
|
||||
// FIXME: should we create a default tileGrid?
|
||||
// we could issue a getCapabilities xhr to retrieve missing configuration
|
||||
const tileGrid = options.tileGrid;
|
||||
|
||||
if (requestEncoding == WMTSRequestEncoding.KVP) {
|
||||
assign(context, {
|
||||
'Service': 'WMTS',
|
||||
'Request': 'GetTile',
|
||||
'Version': this.version_,
|
||||
'Format': this.format_
|
||||
});
|
||||
}
|
||||
// context property names are lower case to allow for a case insensitive
|
||||
// replacement as some services use different naming conventions
|
||||
const context = {
|
||||
'layer': this.layer_,
|
||||
'style': this.style_,
|
||||
'tilematrixset': this.matrixSet_
|
||||
};
|
||||
|
||||
const dimensions = this.dimensions_;
|
||||
|
||||
/**
|
||||
* @param {string} template Template.
|
||||
* @return {module:ol/Tile~UrlFunction} Tile URL function.
|
||||
* @private
|
||||
*/
|
||||
this.createFromWMTSTemplate_ = function(template) {
|
||||
|
||||
// TODO: we may want to create our own appendParams function so that params
|
||||
// order conforms to wmts spec guidance, and so that we can avoid to escape
|
||||
// special template params
|
||||
|
||||
template = (requestEncoding == WMTSRequestEncoding.KVP) ?
|
||||
appendParams(template, context) :
|
||||
template.replace(/\{(\w+?)\}/g, function(m, p) {
|
||||
return (p.toLowerCase() in context) ? context[p.toLowerCase()] : m;
|
||||
if (requestEncoding == WMTSRequestEncoding.KVP) {
|
||||
assign(context, {
|
||||
'Service': 'WMTS',
|
||||
'Request': 'GetTile',
|
||||
'Version': this.version_,
|
||||
'Format': this.format_
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
/**
|
||||
* @param {module:ol/tilecoord~TileCoord} tileCoord Tile coordinate.
|
||||
* @param {number} pixelRatio Pixel ratio.
|
||||
* @param {module:ol/proj/Projection} projection Projection.
|
||||
* @return {string|undefined} Tile URL.
|
||||
*/
|
||||
function(tileCoord, pixelRatio, projection) {
|
||||
if (!tileCoord) {
|
||||
return undefined;
|
||||
} else {
|
||||
const localContext = {
|
||||
'TileMatrix': tileGrid.getMatrixId(tileCoord[0]),
|
||||
'TileCol': tileCoord[1],
|
||||
'TileRow': -tileCoord[2] - 1
|
||||
};
|
||||
assign(localContext, dimensions);
|
||||
let url = template;
|
||||
if (requestEncoding == WMTSRequestEncoding.KVP) {
|
||||
url = appendParams(url, localContext);
|
||||
const dimensions = this.dimensions_;
|
||||
|
||||
/**
|
||||
* @param {string} template Template.
|
||||
* @return {module:ol/Tile~UrlFunction} Tile URL function.
|
||||
* @private
|
||||
*/
|
||||
this.createFromWMTSTemplate_ = function(template) {
|
||||
|
||||
// TODO: we may want to create our own appendParams function so that params
|
||||
// order conforms to wmts spec guidance, and so that we can avoid to escape
|
||||
// special template params
|
||||
|
||||
template = (requestEncoding == WMTSRequestEncoding.KVP) ?
|
||||
appendParams(template, context) :
|
||||
template.replace(/\{(\w+?)\}/g, function(m, p) {
|
||||
return (p.toLowerCase() in context) ? context[p.toLowerCase()] : m;
|
||||
});
|
||||
|
||||
return (
|
||||
/**
|
||||
* @param {module:ol/tilecoord~TileCoord} tileCoord Tile coordinate.
|
||||
* @param {number} pixelRatio Pixel ratio.
|
||||
* @param {module:ol/proj/Projection} projection Projection.
|
||||
* @return {string|undefined} Tile URL.
|
||||
*/
|
||||
function(tileCoord, pixelRatio, projection) {
|
||||
if (!tileCoord) {
|
||||
return undefined;
|
||||
} else {
|
||||
url = url.replace(/\{(\w+?)\}/g, function(m, p) {
|
||||
return localContext[p];
|
||||
});
|
||||
const localContext = {
|
||||
'TileMatrix': tileGrid.getMatrixId(tileCoord[0]),
|
||||
'TileCol': tileCoord[1],
|
||||
'TileRow': -tileCoord[2] - 1
|
||||
};
|
||||
assign(localContext, dimensions);
|
||||
let url = template;
|
||||
if (requestEncoding == WMTSRequestEncoding.KVP) {
|
||||
url = appendParams(url, localContext);
|
||||
} else {
|
||||
url = url.replace(/\{(\w+?)\}/g, function(m, p) {
|
||||
return localContext[p];
|
||||
});
|
||||
}
|
||||
return url;
|
||||
}
|
||||
return url;
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
);
|
||||
};
|
||||
|
||||
const tileUrlFunction = (urls && urls.length > 0) ?
|
||||
createFromTileUrlFunctions(urls.map(this.createFromWMTSTemplate_)) : nullTileUrlFunction;
|
||||
const tileUrlFunction = (urls && urls.length > 0) ?
|
||||
createFromTileUrlFunctions(urls.map(this.createFromWMTSTemplate_)) : nullTileUrlFunction;
|
||||
|
||||
TileImage.call(this, {
|
||||
attributions: options.attributions,
|
||||
cacheSize: options.cacheSize,
|
||||
crossOrigin: options.crossOrigin,
|
||||
projection: options.projection,
|
||||
reprojectionErrorThreshold: options.reprojectionErrorThreshold,
|
||||
tileClass: options.tileClass,
|
||||
tileGrid: tileGrid,
|
||||
tileLoadFunction: options.tileLoadFunction,
|
||||
tilePixelRatio: options.tilePixelRatio,
|
||||
tileUrlFunction: tileUrlFunction,
|
||||
urls: urls,
|
||||
wrapX: options.wrapX !== undefined ? options.wrapX : false,
|
||||
transition: options.transition
|
||||
});
|
||||
TileImage.call(this, {
|
||||
attributions: options.attributions,
|
||||
cacheSize: options.cacheSize,
|
||||
crossOrigin: options.crossOrigin,
|
||||
projection: options.projection,
|
||||
reprojectionErrorThreshold: options.reprojectionErrorThreshold,
|
||||
tileClass: options.tileClass,
|
||||
tileGrid: tileGrid,
|
||||
tileLoadFunction: options.tileLoadFunction,
|
||||
tilePixelRatio: options.tilePixelRatio,
|
||||
tileUrlFunction: tileUrlFunction,
|
||||
urls: urls,
|
||||
wrapX: options.wrapX !== undefined ? options.wrapX : false,
|
||||
transition: options.transition
|
||||
});
|
||||
|
||||
this.setKey(this.getKeyForDimensions_());
|
||||
this.setKey(this.getKeyForDimensions_());
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inherits(WMTS, TileImage);
|
||||
|
||||
|
||||
@@ -66,37 +66,42 @@ import {createXYZ, extentFromProjection} from '../tilegrid.js';
|
||||
* @param {module:ol/source/XYZ~Options=} opt_options XYZ options.
|
||||
* @api
|
||||
*/
|
||||
const XYZ = function(opt_options) {
|
||||
const options = opt_options || {};
|
||||
const projection = options.projection !== undefined ?
|
||||
options.projection : 'EPSG:3857';
|
||||
class XYZ {
|
||||
|
||||
const tileGrid = options.tileGrid !== undefined ? options.tileGrid :
|
||||
createXYZ({
|
||||
extent: extentFromProjection(projection),
|
||||
maxZoom: options.maxZoom,
|
||||
minZoom: options.minZoom,
|
||||
tileSize: options.tileSize
|
||||
constructor(opt_options) {
|
||||
const options = opt_options || {};
|
||||
const projection = options.projection !== undefined ?
|
||||
options.projection : 'EPSG:3857';
|
||||
|
||||
const tileGrid = options.tileGrid !== undefined ? options.tileGrid :
|
||||
createXYZ({
|
||||
extent: extentFromProjection(projection),
|
||||
maxZoom: options.maxZoom,
|
||||
minZoom: options.minZoom,
|
||||
tileSize: options.tileSize
|
||||
});
|
||||
|
||||
TileImage.call(this, {
|
||||
attributions: options.attributions,
|
||||
cacheSize: options.cacheSize,
|
||||
crossOrigin: options.crossOrigin,
|
||||
opaque: options.opaque,
|
||||
projection: projection,
|
||||
reprojectionErrorThreshold: options.reprojectionErrorThreshold,
|
||||
tileGrid: tileGrid,
|
||||
tileLoadFunction: options.tileLoadFunction,
|
||||
tilePixelRatio: options.tilePixelRatio,
|
||||
tileUrlFunction: options.tileUrlFunction,
|
||||
url: options.url,
|
||||
urls: options.urls,
|
||||
wrapX: options.wrapX !== undefined ? options.wrapX : true,
|
||||
transition: options.transition
|
||||
});
|
||||
|
||||
TileImage.call(this, {
|
||||
attributions: options.attributions,
|
||||
cacheSize: options.cacheSize,
|
||||
crossOrigin: options.crossOrigin,
|
||||
opaque: options.opaque,
|
||||
projection: projection,
|
||||
reprojectionErrorThreshold: options.reprojectionErrorThreshold,
|
||||
tileGrid: tileGrid,
|
||||
tileLoadFunction: options.tileLoadFunction,
|
||||
tilePixelRatio: options.tilePixelRatio,
|
||||
tileUrlFunction: options.tileUrlFunction,
|
||||
url: options.url,
|
||||
urls: options.urls,
|
||||
wrapX: options.wrapX !== undefined ? options.wrapX : true,
|
||||
transition: options.transition
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
inherits(XYZ, TileImage);
|
||||
|
||||
export default XYZ;
|
||||
|
||||
@@ -34,23 +34,28 @@ const TierSizeCalculation = {
|
||||
* @param {module:ol/Tile~LoadFunction} tileLoadFunction Tile load function.
|
||||
* @param {module:ol/Tile~Options=} opt_options Tile options.
|
||||
*/
|
||||
export const CustomTile = function(
|
||||
tileGrid, tileCoord, state, src, crossOrigin, tileLoadFunction, opt_options) {
|
||||
export class CustomTile {
|
||||
|
||||
ImageTile.call(this, tileCoord, state, src, crossOrigin, tileLoadFunction, opt_options);
|
||||
constructor(tileGrid, tileCoord, state, src, crossOrigin, tileLoadFunction, opt_options) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement}
|
||||
*/
|
||||
this.zoomifyImage_ = null;
|
||||
ImageTile.call(this, tileCoord, state, src, crossOrigin, tileLoadFunction, opt_options);
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement}
|
||||
*/
|
||||
this.zoomifyImage_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/size~Size}
|
||||
*/
|
||||
this.tileSize_ = toSize(tileGrid.getTileSize(tileCoord[0]));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/size~Size}
|
||||
*/
|
||||
this.tileSize_ = toSize(tileGrid.getTileSize(tileCoord[0]));
|
||||
};
|
||||
inherits(CustomTile, ImageTile);
|
||||
|
||||
|
||||
@@ -124,135 +129,138 @@ CustomTile.prototype.getImage = function() {
|
||||
* @param {module:ol/source/Zoomify~Options=} opt_options Options.
|
||||
* @api
|
||||
*/
|
||||
const Zoomify = function(opt_options) {
|
||||
class Zoomify {
|
||||
|
||||
const options = opt_options || {};
|
||||
constructor(opt_options) {
|
||||
|
||||
const size = options.size;
|
||||
const tierSizeCalculation = options.tierSizeCalculation !== undefined ?
|
||||
options.tierSizeCalculation :
|
||||
TierSizeCalculation.DEFAULT;
|
||||
const options = opt_options || {};
|
||||
|
||||
const imageWidth = size[0];
|
||||
const imageHeight = size[1];
|
||||
const extent = options.extent || [0, -size[1], size[0], 0];
|
||||
const tierSizeInTiles = [];
|
||||
const tileSize = options.tileSize || DEFAULT_TILE_SIZE;
|
||||
let tileSizeForTierSizeCalculation = tileSize;
|
||||
const size = options.size;
|
||||
const tierSizeCalculation = options.tierSizeCalculation !== undefined ?
|
||||
options.tierSizeCalculation :
|
||||
TierSizeCalculation.DEFAULT;
|
||||
|
||||
switch (tierSizeCalculation) {
|
||||
case TierSizeCalculation.DEFAULT:
|
||||
while (imageWidth > tileSizeForTierSizeCalculation || imageHeight > tileSizeForTierSizeCalculation) {
|
||||
tierSizeInTiles.push([
|
||||
Math.ceil(imageWidth / tileSizeForTierSizeCalculation),
|
||||
Math.ceil(imageHeight / tileSizeForTierSizeCalculation)
|
||||
]);
|
||||
tileSizeForTierSizeCalculation += tileSizeForTierSizeCalculation;
|
||||
}
|
||||
break;
|
||||
case TierSizeCalculation.TRUNCATED:
|
||||
let width = imageWidth;
|
||||
let height = imageHeight;
|
||||
while (width > tileSizeForTierSizeCalculation || height > tileSizeForTierSizeCalculation) {
|
||||
tierSizeInTiles.push([
|
||||
Math.ceil(width / tileSizeForTierSizeCalculation),
|
||||
Math.ceil(height / tileSizeForTierSizeCalculation)
|
||||
]);
|
||||
width >>= 1;
|
||||
height >>= 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(false, 53); // Unknown `tierSizeCalculation` configured
|
||||
break;
|
||||
}
|
||||
const imageWidth = size[0];
|
||||
const imageHeight = size[1];
|
||||
const extent = options.extent || [0, -size[1], size[0], 0];
|
||||
const tierSizeInTiles = [];
|
||||
const tileSize = options.tileSize || DEFAULT_TILE_SIZE;
|
||||
let tileSizeForTierSizeCalculation = tileSize;
|
||||
|
||||
tierSizeInTiles.push([1, 1]);
|
||||
tierSizeInTiles.reverse();
|
||||
|
||||
const resolutions = [1];
|
||||
const tileCountUpToTier = [0];
|
||||
for (let i = 1, ii = tierSizeInTiles.length; i < ii; i++) {
|
||||
resolutions.push(1 << i);
|
||||
tileCountUpToTier.push(
|
||||
tierSizeInTiles[i - 1][0] * tierSizeInTiles[i - 1][1] +
|
||||
tileCountUpToTier[i - 1]
|
||||
);
|
||||
}
|
||||
resolutions.reverse();
|
||||
|
||||
const tileGrid = new TileGrid({
|
||||
tileSize: tileSize,
|
||||
extent: extent,
|
||||
origin: getTopLeft(extent),
|
||||
resolutions: resolutions
|
||||
});
|
||||
|
||||
let url = options.url;
|
||||
if (url && url.indexOf('{TileGroup}') == -1 && url.indexOf('{tileIndex}') == -1) {
|
||||
url += '{TileGroup}/{z}-{x}-{y}.jpg';
|
||||
}
|
||||
const urls = expandUrl(url);
|
||||
|
||||
/**
|
||||
* @param {string} template Template.
|
||||
* @return {module:ol/Tile~UrlFunction} Tile URL function.
|
||||
*/
|
||||
function createFromTemplate(template) {
|
||||
|
||||
return (
|
||||
/**
|
||||
* @param {module:ol/tilecoord~TileCoord} tileCoord Tile Coordinate.
|
||||
* @param {number} pixelRatio Pixel ratio.
|
||||
* @param {module:ol/proj/Projection} projection Projection.
|
||||
* @return {string|undefined} Tile URL.
|
||||
*/
|
||||
function(tileCoord, pixelRatio, projection) {
|
||||
if (!tileCoord) {
|
||||
return undefined;
|
||||
} else {
|
||||
const tileCoordZ = tileCoord[0];
|
||||
const tileCoordX = tileCoord[1];
|
||||
const tileCoordY = -tileCoord[2] - 1;
|
||||
const tileIndex =
|
||||
tileCoordX +
|
||||
tileCoordY * tierSizeInTiles[tileCoordZ][0];
|
||||
const tileSize = tileGrid.getTileSize(tileCoordZ);
|
||||
const tileGroup = ((tileIndex + tileCountUpToTier[tileCoordZ]) / tileSize) | 0;
|
||||
const localContext = {
|
||||
'z': tileCoordZ,
|
||||
'x': tileCoordX,
|
||||
'y': tileCoordY,
|
||||
'tileIndex': tileIndex,
|
||||
'TileGroup': 'TileGroup' + tileGroup
|
||||
};
|
||||
return template.replace(/\{(\w+?)\}/g, function(m, p) {
|
||||
return localContext[p];
|
||||
});
|
||||
switch (tierSizeCalculation) {
|
||||
case TierSizeCalculation.DEFAULT:
|
||||
while (imageWidth > tileSizeForTierSizeCalculation || imageHeight > tileSizeForTierSizeCalculation) {
|
||||
tierSizeInTiles.push([
|
||||
Math.ceil(imageWidth / tileSizeForTierSizeCalculation),
|
||||
Math.ceil(imageHeight / tileSizeForTierSizeCalculation)
|
||||
]);
|
||||
tileSizeForTierSizeCalculation += tileSizeForTierSizeCalculation;
|
||||
}
|
||||
}
|
||||
);
|
||||
break;
|
||||
case TierSizeCalculation.TRUNCATED:
|
||||
let width = imageWidth;
|
||||
let height = imageHeight;
|
||||
while (width > tileSizeForTierSizeCalculation || height > tileSizeForTierSizeCalculation) {
|
||||
tierSizeInTiles.push([
|
||||
Math.ceil(width / tileSizeForTierSizeCalculation),
|
||||
Math.ceil(height / tileSizeForTierSizeCalculation)
|
||||
]);
|
||||
width >>= 1;
|
||||
height >>= 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(false, 53); // Unknown `tierSizeCalculation` configured
|
||||
break;
|
||||
}
|
||||
|
||||
tierSizeInTiles.push([1, 1]);
|
||||
tierSizeInTiles.reverse();
|
||||
|
||||
const resolutions = [1];
|
||||
const tileCountUpToTier = [0];
|
||||
for (let i = 1, ii = tierSizeInTiles.length; i < ii; i++) {
|
||||
resolutions.push(1 << i);
|
||||
tileCountUpToTier.push(
|
||||
tierSizeInTiles[i - 1][0] * tierSizeInTiles[i - 1][1] +
|
||||
tileCountUpToTier[i - 1]
|
||||
);
|
||||
}
|
||||
resolutions.reverse();
|
||||
|
||||
const tileGrid = new TileGrid({
|
||||
tileSize: tileSize,
|
||||
extent: extent,
|
||||
origin: getTopLeft(extent),
|
||||
resolutions: resolutions
|
||||
});
|
||||
|
||||
let url = options.url;
|
||||
if (url && url.indexOf('{TileGroup}') == -1 && url.indexOf('{tileIndex}') == -1) {
|
||||
url += '{TileGroup}/{z}-{x}-{y}.jpg';
|
||||
}
|
||||
const urls = expandUrl(url);
|
||||
|
||||
/**
|
||||
* @param {string} template Template.
|
||||
* @return {module:ol/Tile~UrlFunction} Tile URL function.
|
||||
*/
|
||||
function createFromTemplate(template) {
|
||||
|
||||
return (
|
||||
/**
|
||||
* @param {module:ol/tilecoord~TileCoord} tileCoord Tile Coordinate.
|
||||
* @param {number} pixelRatio Pixel ratio.
|
||||
* @param {module:ol/proj/Projection} projection Projection.
|
||||
* @return {string|undefined} Tile URL.
|
||||
*/
|
||||
function(tileCoord, pixelRatio, projection) {
|
||||
if (!tileCoord) {
|
||||
return undefined;
|
||||
} else {
|
||||
const tileCoordZ = tileCoord[0];
|
||||
const tileCoordX = tileCoord[1];
|
||||
const tileCoordY = -tileCoord[2] - 1;
|
||||
const tileIndex =
|
||||
tileCoordX +
|
||||
tileCoordY * tierSizeInTiles[tileCoordZ][0];
|
||||
const tileSize = tileGrid.getTileSize(tileCoordZ);
|
||||
const tileGroup = ((tileIndex + tileCountUpToTier[tileCoordZ]) / tileSize) | 0;
|
||||
const localContext = {
|
||||
'z': tileCoordZ,
|
||||
'x': tileCoordX,
|
||||
'y': tileCoordY,
|
||||
'tileIndex': tileIndex,
|
||||
'TileGroup': 'TileGroup' + tileGroup
|
||||
};
|
||||
return template.replace(/\{(\w+?)\}/g, function(m, p) {
|
||||
return localContext[p];
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
const tileUrlFunction = createFromTileUrlFunctions(urls.map(createFromTemplate));
|
||||
|
||||
const ZoomifyTileClass = CustomTile.bind(null, tileGrid);
|
||||
|
||||
TileImage.call(this, {
|
||||
attributions: options.attributions,
|
||||
cacheSize: options.cacheSize,
|
||||
crossOrigin: options.crossOrigin,
|
||||
projection: options.projection,
|
||||
reprojectionErrorThreshold: options.reprojectionErrorThreshold,
|
||||
tileClass: ZoomifyTileClass,
|
||||
tileGrid: tileGrid,
|
||||
tileUrlFunction: tileUrlFunction,
|
||||
transition: options.transition
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
const tileUrlFunction = createFromTileUrlFunctions(urls.map(createFromTemplate));
|
||||
|
||||
const ZoomifyTileClass = CustomTile.bind(null, tileGrid);
|
||||
|
||||
TileImage.call(this, {
|
||||
attributions: options.attributions,
|
||||
cacheSize: options.cacheSize,
|
||||
crossOrigin: options.crossOrigin,
|
||||
projection: options.projection,
|
||||
reprojectionErrorThreshold: options.reprojectionErrorThreshold,
|
||||
tileClass: ZoomifyTileClass,
|
||||
tileGrid: tileGrid,
|
||||
tileUrlFunction: tileUrlFunction,
|
||||
transition: options.transition
|
||||
});
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
inherits(Zoomify, TileImage);
|
||||
|
||||
|
||||
export default Zoomify;
|
||||
|
||||
@@ -27,272 +27,277 @@ import EventType from '../events/EventType.js';
|
||||
* @template T
|
||||
* @param {number=} opt_highWaterMark High water mark.
|
||||
*/
|
||||
const LRUCache = function(opt_highWaterMark) {
|
||||
class LRUCache {
|
||||
|
||||
constructor(opt_highWaterMark) {
|
||||
|
||||
EventTarget.call(this);
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.highWaterMark = opt_highWaterMark !== undefined ? opt_highWaterMark : 2048;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.count_ = 0;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {!Object.<string, module:ol/structs/LRUCache~Entry>}
|
||||
*/
|
||||
this.entries_ = {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {?module:ol/structs/LRUCache~Entry}
|
||||
*/
|
||||
this.oldest_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {?module:ol/structs/LRUCache~Entry}
|
||||
*/
|
||||
this.newest_ = null;
|
||||
|
||||
}
|
||||
|
||||
EventTarget.call(this);
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
* @return {boolean} Can expire cache.
|
||||
*/
|
||||
this.highWaterMark = opt_highWaterMark !== undefined ? opt_highWaterMark : 2048;
|
||||
canExpireCache() {
|
||||
return this.getCount() > this.highWaterMark;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
* FIXME empty description for jsdoc
|
||||
*/
|
||||
this.count_ = 0;
|
||||
clear() {
|
||||
this.count_ = 0;
|
||||
this.entries_ = {};
|
||||
this.oldest_ = null;
|
||||
this.newest_ = null;
|
||||
this.dispatchEvent(EventType.CLEAR);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {!Object.<string, module:ol/structs/LRUCache~Entry>}
|
||||
* @param {string} key Key.
|
||||
* @return {boolean} Contains key.
|
||||
*/
|
||||
this.entries_ = {};
|
||||
containsKey(key) {
|
||||
return this.entries_.hasOwnProperty(key);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {?module:ol/structs/LRUCache~Entry}
|
||||
* @param {function(this: S, T, string, module:ol/structs/LRUCache): ?} f The function
|
||||
* to call for every entry from the oldest to the newer. This function takes
|
||||
* 3 arguments (the entry value, the entry key and the LRUCache object).
|
||||
* The return value is ignored.
|
||||
* @param {S=} opt_this The object to use as `this` in `f`.
|
||||
* @template S
|
||||
*/
|
||||
this.oldest_ = null;
|
||||
forEach(f, opt_this) {
|
||||
let entry = this.oldest_;
|
||||
while (entry) {
|
||||
f.call(opt_this, entry.value_, entry.key_, this);
|
||||
entry = entry.newer;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {?module:ol/structs/LRUCache~Entry}
|
||||
* @param {string} key Key.
|
||||
* @return {T} Value.
|
||||
*/
|
||||
this.newest_ = null;
|
||||
get(key) {
|
||||
const entry = this.entries_[key];
|
||||
assert(entry !== undefined,
|
||||
15); // Tried to get a value for a key that does not exist in the cache
|
||||
if (entry === this.newest_) {
|
||||
return entry.value_;
|
||||
} else if (entry === this.oldest_) {
|
||||
this.oldest_ = /** @type {module:ol/structs/LRUCache~Entry} */ (this.oldest_.newer);
|
||||
this.oldest_.older = null;
|
||||
} else {
|
||||
entry.newer.older = entry.older;
|
||||
entry.older.newer = entry.newer;
|
||||
}
|
||||
entry.newer = null;
|
||||
entry.older = this.newest_;
|
||||
this.newest_.newer = entry;
|
||||
this.newest_ = entry;
|
||||
return entry.value_;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove an entry from the cache.
|
||||
* @param {string} key The entry key.
|
||||
* @return {T} The removed entry.
|
||||
*/
|
||||
remove(key) {
|
||||
const entry = this.entries_[key];
|
||||
assert(entry !== undefined, 15); // Tried to get a value for a key that does not exist in the cache
|
||||
if (entry === this.newest_) {
|
||||
this.newest_ = /** @type {module:ol/structs/LRUCache~Entry} */ (entry.older);
|
||||
if (this.newest_) {
|
||||
this.newest_.newer = null;
|
||||
}
|
||||
} else if (entry === this.oldest_) {
|
||||
this.oldest_ = /** @type {module:ol/structs/LRUCache~Entry} */ (entry.newer);
|
||||
if (this.oldest_) {
|
||||
this.oldest_.older = null;
|
||||
}
|
||||
} else {
|
||||
entry.newer.older = entry.older;
|
||||
entry.older.newer = entry.newer;
|
||||
}
|
||||
delete this.entries_[key];
|
||||
--this.count_;
|
||||
return entry.value_;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} Count.
|
||||
*/
|
||||
getCount() {
|
||||
return this.count_;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return {Array.<string>} Keys.
|
||||
*/
|
||||
getKeys() {
|
||||
const keys = new Array(this.count_);
|
||||
let i = 0;
|
||||
let entry;
|
||||
for (entry = this.newest_; entry; entry = entry.older) {
|
||||
keys[i++] = entry.key_;
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return {Array.<T>} Values.
|
||||
*/
|
||||
getValues() {
|
||||
const values = new Array(this.count_);
|
||||
let i = 0;
|
||||
let entry;
|
||||
for (entry = this.newest_; entry; entry = entry.older) {
|
||||
values[i++] = entry.value_;
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return {T} Last value.
|
||||
*/
|
||||
peekLast() {
|
||||
return this.oldest_.value_;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return {string} Last key.
|
||||
*/
|
||||
peekLastKey() {
|
||||
return this.oldest_.key_;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the key of the newest item in the cache. Throws if the cache is empty.
|
||||
* @return {string} The newest key.
|
||||
*/
|
||||
peekFirstKey() {
|
||||
return this.newest_.key_;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return {T} value Value.
|
||||
*/
|
||||
pop() {
|
||||
const entry = this.oldest_;
|
||||
delete this.entries_[entry.key_];
|
||||
if (entry.newer) {
|
||||
entry.newer.older = null;
|
||||
}
|
||||
this.oldest_ = /** @type {module:ol/structs/LRUCache~Entry} */ (entry.newer);
|
||||
if (!this.oldest_) {
|
||||
this.newest_ = null;
|
||||
}
|
||||
--this.count_;
|
||||
return entry.value_;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} key Key.
|
||||
* @param {T} value Value.
|
||||
*/
|
||||
replace(key, value) {
|
||||
this.get(key); // update `newest_`
|
||||
this.entries_[key].value_ = value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} key Key.
|
||||
* @param {T} value Value.
|
||||
*/
|
||||
set(key, value) {
|
||||
assert(!(key in this.entries_),
|
||||
16); // Tried to set a value for a key that is used already
|
||||
const entry = /** @type {module:ol/structs/LRUCache~Entry} */ ({
|
||||
key_: key,
|
||||
newer: null,
|
||||
older: this.newest_,
|
||||
value_: value
|
||||
});
|
||||
if (!this.newest_) {
|
||||
this.oldest_ = entry;
|
||||
} else {
|
||||
this.newest_.newer = entry;
|
||||
}
|
||||
this.newest_ = entry;
|
||||
this.entries_[key] = entry;
|
||||
++this.count_;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set a maximum number of entries for the cache.
|
||||
* @param {number} size Cache size.
|
||||
* @api
|
||||
*/
|
||||
setSize(size) {
|
||||
this.highWaterMark = size;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Prune the cache.
|
||||
*/
|
||||
prune() {
|
||||
while (this.canExpireCache()) {
|
||||
this.pop();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inherits(LRUCache, EventTarget);
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Can expire cache.
|
||||
*/
|
||||
LRUCache.prototype.canExpireCache = function() {
|
||||
return this.getCount() > this.highWaterMark;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* FIXME empty description for jsdoc
|
||||
*/
|
||||
LRUCache.prototype.clear = function() {
|
||||
this.count_ = 0;
|
||||
this.entries_ = {};
|
||||
this.oldest_ = null;
|
||||
this.newest_ = null;
|
||||
this.dispatchEvent(EventType.CLEAR);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} key Key.
|
||||
* @return {boolean} Contains key.
|
||||
*/
|
||||
LRUCache.prototype.containsKey = function(key) {
|
||||
return this.entries_.hasOwnProperty(key);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {function(this: S, T, string, module:ol/structs/LRUCache): ?} f The function
|
||||
* to call for every entry from the oldest to the newer. This function takes
|
||||
* 3 arguments (the entry value, the entry key and the LRUCache object).
|
||||
* The return value is ignored.
|
||||
* @param {S=} opt_this The object to use as `this` in `f`.
|
||||
* @template S
|
||||
*/
|
||||
LRUCache.prototype.forEach = function(f, opt_this) {
|
||||
let entry = this.oldest_;
|
||||
while (entry) {
|
||||
f.call(opt_this, entry.value_, entry.key_, this);
|
||||
entry = entry.newer;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} key Key.
|
||||
* @return {T} Value.
|
||||
*/
|
||||
LRUCache.prototype.get = function(key) {
|
||||
const entry = this.entries_[key];
|
||||
assert(entry !== undefined,
|
||||
15); // Tried to get a value for a key that does not exist in the cache
|
||||
if (entry === this.newest_) {
|
||||
return entry.value_;
|
||||
} else if (entry === this.oldest_) {
|
||||
this.oldest_ = /** @type {module:ol/structs/LRUCache~Entry} */ (this.oldest_.newer);
|
||||
this.oldest_.older = null;
|
||||
} else {
|
||||
entry.newer.older = entry.older;
|
||||
entry.older.newer = entry.newer;
|
||||
}
|
||||
entry.newer = null;
|
||||
entry.older = this.newest_;
|
||||
this.newest_.newer = entry;
|
||||
this.newest_ = entry;
|
||||
return entry.value_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Remove an entry from the cache.
|
||||
* @param {string} key The entry key.
|
||||
* @return {T} The removed entry.
|
||||
*/
|
||||
LRUCache.prototype.remove = function(key) {
|
||||
const entry = this.entries_[key];
|
||||
assert(entry !== undefined, 15); // Tried to get a value for a key that does not exist in the cache
|
||||
if (entry === this.newest_) {
|
||||
this.newest_ = /** @type {module:ol/structs/LRUCache~Entry} */ (entry.older);
|
||||
if (this.newest_) {
|
||||
this.newest_.newer = null;
|
||||
}
|
||||
} else if (entry === this.oldest_) {
|
||||
this.oldest_ = /** @type {module:ol/structs/LRUCache~Entry} */ (entry.newer);
|
||||
if (this.oldest_) {
|
||||
this.oldest_.older = null;
|
||||
}
|
||||
} else {
|
||||
entry.newer.older = entry.older;
|
||||
entry.older.newer = entry.newer;
|
||||
}
|
||||
delete this.entries_[key];
|
||||
--this.count_;
|
||||
return entry.value_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} Count.
|
||||
*/
|
||||
LRUCache.prototype.getCount = function() {
|
||||
return this.count_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {Array.<string>} Keys.
|
||||
*/
|
||||
LRUCache.prototype.getKeys = function() {
|
||||
const keys = new Array(this.count_);
|
||||
let i = 0;
|
||||
let entry;
|
||||
for (entry = this.newest_; entry; entry = entry.older) {
|
||||
keys[i++] = entry.key_;
|
||||
}
|
||||
return keys;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {Array.<T>} Values.
|
||||
*/
|
||||
LRUCache.prototype.getValues = function() {
|
||||
const values = new Array(this.count_);
|
||||
let i = 0;
|
||||
let entry;
|
||||
for (entry = this.newest_; entry; entry = entry.older) {
|
||||
values[i++] = entry.value_;
|
||||
}
|
||||
return values;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {T} Last value.
|
||||
*/
|
||||
LRUCache.prototype.peekLast = function() {
|
||||
return this.oldest_.value_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {string} Last key.
|
||||
*/
|
||||
LRUCache.prototype.peekLastKey = function() {
|
||||
return this.oldest_.key_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the key of the newest item in the cache. Throws if the cache is empty.
|
||||
* @return {string} The newest key.
|
||||
*/
|
||||
LRUCache.prototype.peekFirstKey = function() {
|
||||
return this.newest_.key_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {T} value Value.
|
||||
*/
|
||||
LRUCache.prototype.pop = function() {
|
||||
const entry = this.oldest_;
|
||||
delete this.entries_[entry.key_];
|
||||
if (entry.newer) {
|
||||
entry.newer.older = null;
|
||||
}
|
||||
this.oldest_ = /** @type {module:ol/structs/LRUCache~Entry} */ (entry.newer);
|
||||
if (!this.oldest_) {
|
||||
this.newest_ = null;
|
||||
}
|
||||
--this.count_;
|
||||
return entry.value_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} key Key.
|
||||
* @param {T} value Value.
|
||||
*/
|
||||
LRUCache.prototype.replace = function(key, value) {
|
||||
this.get(key); // update `newest_`
|
||||
this.entries_[key].value_ = value;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} key Key.
|
||||
* @param {T} value Value.
|
||||
*/
|
||||
LRUCache.prototype.set = function(key, value) {
|
||||
assert(!(key in this.entries_),
|
||||
16); // Tried to set a value for a key that is used already
|
||||
const entry = /** @type {module:ol/structs/LRUCache~Entry} */ ({
|
||||
key_: key,
|
||||
newer: null,
|
||||
older: this.newest_,
|
||||
value_: value
|
||||
});
|
||||
if (!this.newest_) {
|
||||
this.oldest_ = entry;
|
||||
} else {
|
||||
this.newest_.newer = entry;
|
||||
}
|
||||
this.newest_ = entry;
|
||||
this.entries_[key] = entry;
|
||||
++this.count_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set a maximum number of entries for the cache.
|
||||
* @param {number} size Cache size.
|
||||
* @api
|
||||
*/
|
||||
LRUCache.prototype.setSize = function(size) {
|
||||
this.highWaterMark = size;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Prune the cache.
|
||||
*/
|
||||
LRUCache.prototype.prune = function() {
|
||||
while (this.canExpireCache()) {
|
||||
this.pop();
|
||||
}
|
||||
};
|
||||
export default LRUCache;
|
||||
|
||||
@@ -19,242 +19,249 @@
|
||||
* @param {boolean=} opt_circular The last item is connected to the first one,
|
||||
* and the first item to the last one. Default is true.
|
||||
*/
|
||||
const LinkedList = function(opt_circular) {
|
||||
class LinkedList {
|
||||
|
||||
constructor(opt_circular) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/structs/LinkedList~Item|undefined}
|
||||
*/
|
||||
this.first_;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/structs/LinkedList~Item|undefined}
|
||||
*/
|
||||
this.last_;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/structs/LinkedList~Item|undefined}
|
||||
*/
|
||||
this.head_;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.circular_ = opt_circular === undefined ? true : opt_circular;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.length_ = 0;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/structs/LinkedList~Item|undefined}
|
||||
* Inserts an item into the linked list right after the current one.
|
||||
*
|
||||
* @param {?} data Item data.
|
||||
*/
|
||||
this.first_;
|
||||
insertItem(data) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/structs/LinkedList~Item|undefined}
|
||||
*/
|
||||
this.last_;
|
||||
/** @type {module:ol/structs/LinkedList~Item} */
|
||||
const item = {
|
||||
prev: undefined,
|
||||
next: undefined,
|
||||
data: data
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/structs/LinkedList~Item|undefined}
|
||||
*/
|
||||
this.head_;
|
||||
const head = this.head_;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.circular_ = opt_circular === undefined ? true : opt_circular;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.length_ = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Inserts an item into the linked list right after the current one.
|
||||
*
|
||||
* @param {?} data Item data.
|
||||
*/
|
||||
LinkedList.prototype.insertItem = function(data) {
|
||||
|
||||
/** @type {module:ol/structs/LinkedList~Item} */
|
||||
const item = {
|
||||
prev: undefined,
|
||||
next: undefined,
|
||||
data: data
|
||||
};
|
||||
|
||||
const head = this.head_;
|
||||
|
||||
//Initialize the list.
|
||||
if (!head) {
|
||||
this.first_ = item;
|
||||
this.last_ = item;
|
||||
if (this.circular_) {
|
||||
item.next = item;
|
||||
item.prev = item;
|
||||
}
|
||||
} else {
|
||||
//Link the new item to the adjacent ones.
|
||||
const next = head.next;
|
||||
item.prev = head;
|
||||
item.next = next;
|
||||
head.next = item;
|
||||
if (next) {
|
||||
next.prev = item;
|
||||
}
|
||||
|
||||
if (head === this.last_) {
|
||||
//Initialize the list.
|
||||
if (!head) {
|
||||
this.first_ = item;
|
||||
this.last_ = item;
|
||||
}
|
||||
}
|
||||
this.head_ = item;
|
||||
this.length_++;
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes the current item from the list. Sets the cursor to the next item,
|
||||
* if possible.
|
||||
*/
|
||||
LinkedList.prototype.removeItem = function() {
|
||||
const head = this.head_;
|
||||
if (head) {
|
||||
const next = head.next;
|
||||
const prev = head.prev;
|
||||
if (next) {
|
||||
next.prev = prev;
|
||||
}
|
||||
if (prev) {
|
||||
prev.next = next;
|
||||
}
|
||||
this.head_ = next || prev;
|
||||
|
||||
if (this.first_ === this.last_) {
|
||||
this.head_ = undefined;
|
||||
this.first_ = undefined;
|
||||
this.last_ = undefined;
|
||||
} else if (this.first_ === head) {
|
||||
this.first_ = this.head_;
|
||||
} else if (this.last_ === head) {
|
||||
this.last_ = prev ? this.head_.prev : this.head_;
|
||||
}
|
||||
this.length_--;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the cursor to the first item, and returns the associated data.
|
||||
*
|
||||
* @return {?} Item data.
|
||||
*/
|
||||
LinkedList.prototype.firstItem = function() {
|
||||
this.head_ = this.first_;
|
||||
if (this.head_) {
|
||||
return this.head_.data;
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the cursor to the last item, and returns the associated data.
|
||||
*
|
||||
* @return {?} Item data.
|
||||
*/
|
||||
LinkedList.prototype.lastItem = function() {
|
||||
this.head_ = this.last_;
|
||||
if (this.head_) {
|
||||
return this.head_.data;
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the cursor to the next item, and returns the associated data.
|
||||
*
|
||||
* @return {?} Item data.
|
||||
*/
|
||||
LinkedList.prototype.nextItem = function() {
|
||||
if (this.head_ && this.head_.next) {
|
||||
this.head_ = this.head_.next;
|
||||
return this.head_.data;
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the next item's data without moving the cursor.
|
||||
*
|
||||
* @return {?} Item data.
|
||||
*/
|
||||
LinkedList.prototype.getNextItem = function() {
|
||||
if (this.head_ && this.head_.next) {
|
||||
return this.head_.next.data;
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the cursor to the previous item, and returns the associated data.
|
||||
*
|
||||
* @return {?} Item data.
|
||||
*/
|
||||
LinkedList.prototype.prevItem = function() {
|
||||
if (this.head_ && this.head_.prev) {
|
||||
this.head_ = this.head_.prev;
|
||||
return this.head_.data;
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the previous item's data without moving the cursor.
|
||||
*
|
||||
* @return {?} Item data.
|
||||
*/
|
||||
LinkedList.prototype.getPrevItem = function() {
|
||||
if (this.head_ && this.head_.prev) {
|
||||
return this.head_.prev.data;
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the current item's data.
|
||||
*
|
||||
* @return {?} Item data.
|
||||
*/
|
||||
LinkedList.prototype.getCurrItem = function() {
|
||||
if (this.head_) {
|
||||
return this.head_.data;
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the first item of the list. This only works for circular lists, and sets
|
||||
* the last item accordingly.
|
||||
*/
|
||||
LinkedList.prototype.setFirstItem = function() {
|
||||
if (this.circular_ && this.head_) {
|
||||
this.first_ = this.head_;
|
||||
this.last_ = this.head_.prev;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Concatenates two lists.
|
||||
* @param {module:ol/structs/LinkedList} list List to merge into the current list.
|
||||
*/
|
||||
LinkedList.prototype.concat = function(list) {
|
||||
if (list.head_) {
|
||||
if (this.head_) {
|
||||
const end = this.head_.next;
|
||||
this.head_.next = list.first_;
|
||||
list.first_.prev = this.head_;
|
||||
end.prev = list.last_;
|
||||
list.last_.next = end;
|
||||
this.length_ += list.length_;
|
||||
if (this.circular_) {
|
||||
item.next = item;
|
||||
item.prev = item;
|
||||
}
|
||||
} else {
|
||||
this.head_ = list.head_;
|
||||
this.first_ = list.first_;
|
||||
this.last_ = list.last_;
|
||||
this.length_ = list.length_;
|
||||
}
|
||||
list.head_ = undefined;
|
||||
list.first_ = undefined;
|
||||
list.last_ = undefined;
|
||||
list.length_ = 0;
|
||||
}
|
||||
};
|
||||
//Link the new item to the adjacent ones.
|
||||
const next = head.next;
|
||||
item.prev = head;
|
||||
item.next = next;
|
||||
head.next = item;
|
||||
if (next) {
|
||||
next.prev = item;
|
||||
}
|
||||
|
||||
if (head === this.last_) {
|
||||
this.last_ = item;
|
||||
}
|
||||
}
|
||||
this.head_ = item;
|
||||
this.length_++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the current item from the list. Sets the cursor to the next item,
|
||||
* if possible.
|
||||
*/
|
||||
removeItem() {
|
||||
const head = this.head_;
|
||||
if (head) {
|
||||
const next = head.next;
|
||||
const prev = head.prev;
|
||||
if (next) {
|
||||
next.prev = prev;
|
||||
}
|
||||
if (prev) {
|
||||
prev.next = next;
|
||||
}
|
||||
this.head_ = next || prev;
|
||||
|
||||
if (this.first_ === this.last_) {
|
||||
this.head_ = undefined;
|
||||
this.first_ = undefined;
|
||||
this.last_ = undefined;
|
||||
} else if (this.first_ === head) {
|
||||
this.first_ = this.head_;
|
||||
} else if (this.last_ === head) {
|
||||
this.last_ = prev ? this.head_.prev : this.head_;
|
||||
}
|
||||
this.length_--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the cursor to the first item, and returns the associated data.
|
||||
*
|
||||
* @return {?} Item data.
|
||||
*/
|
||||
firstItem() {
|
||||
this.head_ = this.first_;
|
||||
if (this.head_) {
|
||||
return this.head_.data;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the cursor to the last item, and returns the associated data.
|
||||
*
|
||||
* @return {?} Item data.
|
||||
*/
|
||||
lastItem() {
|
||||
this.head_ = this.last_;
|
||||
if (this.head_) {
|
||||
return this.head_.data;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the cursor to the next item, and returns the associated data.
|
||||
*
|
||||
* @return {?} Item data.
|
||||
*/
|
||||
nextItem() {
|
||||
if (this.head_ && this.head_.next) {
|
||||
this.head_ = this.head_.next;
|
||||
return this.head_.data;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next item's data without moving the cursor.
|
||||
*
|
||||
* @return {?} Item data.
|
||||
*/
|
||||
getNextItem() {
|
||||
if (this.head_ && this.head_.next) {
|
||||
return this.head_.next.data;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the cursor to the previous item, and returns the associated data.
|
||||
*
|
||||
* @return {?} Item data.
|
||||
*/
|
||||
prevItem() {
|
||||
if (this.head_ && this.head_.prev) {
|
||||
this.head_ = this.head_.prev;
|
||||
return this.head_.data;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the previous item's data without moving the cursor.
|
||||
*
|
||||
* @return {?} Item data.
|
||||
*/
|
||||
getPrevItem() {
|
||||
if (this.head_ && this.head_.prev) {
|
||||
return this.head_.prev.data;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current item's data.
|
||||
*
|
||||
* @return {?} Item data.
|
||||
*/
|
||||
getCurrItem() {
|
||||
if (this.head_) {
|
||||
return this.head_.data;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the first item of the list. This only works for circular lists, and sets
|
||||
* the last item accordingly.
|
||||
*/
|
||||
setFirstItem() {
|
||||
if (this.circular_ && this.head_) {
|
||||
this.first_ = this.head_;
|
||||
this.last_ = this.head_.prev;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Concatenates two lists.
|
||||
* @param {module:ol/structs/LinkedList} list List to merge into the current list.
|
||||
*/
|
||||
concat(list) {
|
||||
if (list.head_) {
|
||||
if (this.head_) {
|
||||
const end = this.head_.next;
|
||||
this.head_.next = list.first_;
|
||||
list.first_.prev = this.head_;
|
||||
end.prev = list.last_;
|
||||
list.last_.next = end;
|
||||
this.length_ += list.length_;
|
||||
} else {
|
||||
this.head_ = list.head_;
|
||||
this.first_ = list.first_;
|
||||
this.last_ = list.last_;
|
||||
this.length_ = list.length_;
|
||||
}
|
||||
list.head_ = undefined;
|
||||
list.first_ = undefined;
|
||||
list.last_ = undefined;
|
||||
list.length_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current length of the list.
|
||||
*
|
||||
* @return {number} Length.
|
||||
*/
|
||||
getLength() {
|
||||
return this.length_;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the current length of the list.
|
||||
*
|
||||
* @return {number} Length.
|
||||
*/
|
||||
LinkedList.prototype.getLength = function() {
|
||||
return this.length_;
|
||||
};
|
||||
export default LinkedList;
|
||||
|
||||
@@ -4,6 +4,13 @@
|
||||
import {assert} from '../asserts.js';
|
||||
import {clear} from '../obj.js';
|
||||
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
export const DROP = Infinity;
|
||||
|
||||
|
||||
/**
|
||||
* Priority queue.
|
||||
*
|
||||
@@ -19,257 +26,256 @@ import {clear} from '../obj.js';
|
||||
* @struct
|
||||
* @template T
|
||||
*/
|
||||
const PriorityQueue = function(priorityFunction, keyFunction) {
|
||||
class PriorityQueue {
|
||||
|
||||
/**
|
||||
* @type {function(T): number}
|
||||
* @private
|
||||
*/
|
||||
this.priorityFunction_ = priorityFunction;
|
||||
constructor(priorityFunction, keyFunction) {
|
||||
|
||||
/**
|
||||
* @type {function(T): string}
|
||||
* @private
|
||||
*/
|
||||
this.keyFunction_ = keyFunction;
|
||||
/**
|
||||
* @type {function(T): number}
|
||||
* @private
|
||||
*/
|
||||
this.priorityFunction_ = priorityFunction;
|
||||
|
||||
/**
|
||||
* @type {Array.<T>}
|
||||
* @private
|
||||
*/
|
||||
this.elements_ = [];
|
||||
/**
|
||||
* @type {function(T): string}
|
||||
* @private
|
||||
*/
|
||||
this.keyFunction_ = keyFunction;
|
||||
|
||||
/**
|
||||
* @type {Array.<number>}
|
||||
* @private
|
||||
*/
|
||||
this.priorities_ = [];
|
||||
/**
|
||||
* @type {Array.<T>}
|
||||
* @private
|
||||
*/
|
||||
this.elements_ = [];
|
||||
|
||||
/**
|
||||
* @type {!Object.<string, boolean>}
|
||||
* @private
|
||||
*/
|
||||
this.queuedElements_ = {};
|
||||
/**
|
||||
* @type {Array.<number>}
|
||||
* @private
|
||||
*/
|
||||
this.priorities_ = [];
|
||||
|
||||
};
|
||||
/**
|
||||
* @type {!Object.<string, boolean>}
|
||||
* @private
|
||||
*/
|
||||
this.queuedElements_ = {};
|
||||
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
export const DROP = Infinity;
|
||||
|
||||
|
||||
/**
|
||||
* FIXME empty description for jsdoc
|
||||
*/
|
||||
PriorityQueue.prototype.clear = function() {
|
||||
this.elements_.length = 0;
|
||||
this.priorities_.length = 0;
|
||||
clear(this.queuedElements_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Remove and return the highest-priority element. O(log N).
|
||||
* @return {T} Element.
|
||||
*/
|
||||
PriorityQueue.prototype.dequeue = function() {
|
||||
const elements = this.elements_;
|
||||
const priorities = this.priorities_;
|
||||
const element = elements[0];
|
||||
if (elements.length == 1) {
|
||||
elements.length = 0;
|
||||
priorities.length = 0;
|
||||
} else {
|
||||
elements[0] = elements.pop();
|
||||
priorities[0] = priorities.pop();
|
||||
this.siftUp_(0);
|
||||
}
|
||||
const elementKey = this.keyFunction_(element);
|
||||
delete this.queuedElements_[elementKey];
|
||||
return element;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Enqueue an element. O(log N).
|
||||
* @param {T} element Element.
|
||||
* @return {boolean} The element was added to the queue.
|
||||
*/
|
||||
PriorityQueue.prototype.enqueue = function(element) {
|
||||
assert(!(this.keyFunction_(element) in this.queuedElements_),
|
||||
31); // Tried to enqueue an `element` that was already added to the queue
|
||||
const priority = this.priorityFunction_(element);
|
||||
if (priority != DROP) {
|
||||
this.elements_.push(element);
|
||||
this.priorities_.push(priority);
|
||||
this.queuedElements_[this.keyFunction_(element)] = true;
|
||||
this.siftDown_(0, this.elements_.length - 1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} Count.
|
||||
*/
|
||||
PriorityQueue.prototype.getCount = function() {
|
||||
return this.elements_.length;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets the index of the left child of the node at the given index.
|
||||
* @param {number} index The index of the node to get the left child for.
|
||||
* @return {number} The index of the left child.
|
||||
* @private
|
||||
*/
|
||||
PriorityQueue.prototype.getLeftChildIndex_ = function(index) {
|
||||
return index * 2 + 1;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets the index of the right child of the node at the given index.
|
||||
* @param {number} index The index of the node to get the right child for.
|
||||
* @return {number} The index of the right child.
|
||||
* @private
|
||||
*/
|
||||
PriorityQueue.prototype.getRightChildIndex_ = function(index) {
|
||||
return index * 2 + 2;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets the index of the parent of the node at the given index.
|
||||
* @param {number} index The index of the node to get the parent for.
|
||||
* @return {number} The index of the parent.
|
||||
* @private
|
||||
*/
|
||||
PriorityQueue.prototype.getParentIndex_ = function(index) {
|
||||
return (index - 1) >> 1;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Make this a heap. O(N).
|
||||
* @private
|
||||
*/
|
||||
PriorityQueue.prototype.heapify_ = function() {
|
||||
let i;
|
||||
for (i = (this.elements_.length >> 1) - 1; i >= 0; i--) {
|
||||
this.siftUp_(i);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Is empty.
|
||||
*/
|
||||
PriorityQueue.prototype.isEmpty = function() {
|
||||
return this.elements_.length === 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} key Key.
|
||||
* @return {boolean} Is key queued.
|
||||
*/
|
||||
PriorityQueue.prototype.isKeyQueued = function(key) {
|
||||
return key in this.queuedElements_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {T} element Element.
|
||||
* @return {boolean} Is queued.
|
||||
*/
|
||||
PriorityQueue.prototype.isQueued = function(element) {
|
||||
return this.isKeyQueued(this.keyFunction_(element));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} index The index of the node to move down.
|
||||
* @private
|
||||
*/
|
||||
PriorityQueue.prototype.siftUp_ = function(index) {
|
||||
const elements = this.elements_;
|
||||
const priorities = this.priorities_;
|
||||
const count = elements.length;
|
||||
const element = elements[index];
|
||||
const priority = priorities[index];
|
||||
const startIndex = index;
|
||||
|
||||
while (index < (count >> 1)) {
|
||||
const lIndex = this.getLeftChildIndex_(index);
|
||||
const rIndex = this.getRightChildIndex_(index);
|
||||
|
||||
const smallerChildIndex = rIndex < count &&
|
||||
priorities[rIndex] < priorities[lIndex] ?
|
||||
rIndex : lIndex;
|
||||
|
||||
elements[index] = elements[smallerChildIndex];
|
||||
priorities[index] = priorities[smallerChildIndex];
|
||||
index = smallerChildIndex;
|
||||
}
|
||||
|
||||
elements[index] = element;
|
||||
priorities[index] = priority;
|
||||
this.siftDown_(startIndex, index);
|
||||
};
|
||||
/**
|
||||
* FIXME empty description for jsdoc
|
||||
*/
|
||||
clear() {
|
||||
this.elements_.length = 0;
|
||||
this.priorities_.length = 0;
|
||||
clear(this.queuedElements_);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} startIndex The index of the root.
|
||||
* @param {number} index The index of the node to move up.
|
||||
* @private
|
||||
*/
|
||||
PriorityQueue.prototype.siftDown_ = function(startIndex, index) {
|
||||
const elements = this.elements_;
|
||||
const priorities = this.priorities_;
|
||||
const element = elements[index];
|
||||
const priority = priorities[index];
|
||||
|
||||
while (index > startIndex) {
|
||||
const parentIndex = this.getParentIndex_(index);
|
||||
if (priorities[parentIndex] > priority) {
|
||||
elements[index] = elements[parentIndex];
|
||||
priorities[index] = priorities[parentIndex];
|
||||
index = parentIndex;
|
||||
/**
|
||||
* Remove and return the highest-priority element. O(log N).
|
||||
* @return {T} Element.
|
||||
*/
|
||||
dequeue() {
|
||||
const elements = this.elements_;
|
||||
const priorities = this.priorities_;
|
||||
const element = elements[0];
|
||||
if (elements.length == 1) {
|
||||
elements.length = 0;
|
||||
priorities.length = 0;
|
||||
} else {
|
||||
break;
|
||||
elements[0] = elements.pop();
|
||||
priorities[0] = priorities.pop();
|
||||
this.siftUp_(0);
|
||||
}
|
||||
const elementKey = this.keyFunction_(element);
|
||||
delete this.queuedElements_[elementKey];
|
||||
return element;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Enqueue an element. O(log N).
|
||||
* @param {T} element Element.
|
||||
* @return {boolean} The element was added to the queue.
|
||||
*/
|
||||
enqueue(element) {
|
||||
assert(!(this.keyFunction_(element) in this.queuedElements_),
|
||||
31); // Tried to enqueue an `element` that was already added to the queue
|
||||
const priority = this.priorityFunction_(element);
|
||||
if (priority != DROP) {
|
||||
this.elements_.push(element);
|
||||
this.priorities_.push(priority);
|
||||
this.queuedElements_[this.keyFunction_(element)] = true;
|
||||
this.siftDown_(0, this.elements_.length - 1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} Count.
|
||||
*/
|
||||
getCount() {
|
||||
return this.elements_.length;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the index of the left child of the node at the given index.
|
||||
* @param {number} index The index of the node to get the left child for.
|
||||
* @return {number} The index of the left child.
|
||||
* @private
|
||||
*/
|
||||
getLeftChildIndex_(index) {
|
||||
return index * 2 + 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the index of the right child of the node at the given index.
|
||||
* @param {number} index The index of the node to get the right child for.
|
||||
* @return {number} The index of the right child.
|
||||
* @private
|
||||
*/
|
||||
getRightChildIndex_(index) {
|
||||
return index * 2 + 2;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the index of the parent of the node at the given index.
|
||||
* @param {number} index The index of the node to get the parent for.
|
||||
* @return {number} The index of the parent.
|
||||
* @private
|
||||
*/
|
||||
getParentIndex_(index) {
|
||||
return (index - 1) >> 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Make this a heap. O(N).
|
||||
* @private
|
||||
*/
|
||||
heapify_() {
|
||||
let i;
|
||||
for (i = (this.elements_.length >> 1) - 1; i >= 0; i--) {
|
||||
this.siftUp_(i);
|
||||
}
|
||||
}
|
||||
elements[index] = element;
|
||||
priorities[index] = priority;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* FIXME empty description for jsdoc
|
||||
*/
|
||||
PriorityQueue.prototype.reprioritize = function() {
|
||||
const priorityFunction = this.priorityFunction_;
|
||||
const elements = this.elements_;
|
||||
const priorities = this.priorities_;
|
||||
let index = 0;
|
||||
const n = elements.length;
|
||||
let element, i, priority;
|
||||
for (i = 0; i < n; ++i) {
|
||||
element = elements[i];
|
||||
priority = priorityFunction(element);
|
||||
if (priority == DROP) {
|
||||
delete this.queuedElements_[this.keyFunction_(element)];
|
||||
} else {
|
||||
priorities[index] = priority;
|
||||
elements[index++] = element;
|
||||
}
|
||||
/**
|
||||
* @return {boolean} Is empty.
|
||||
*/
|
||||
isEmpty() {
|
||||
return this.elements_.length === 0;
|
||||
}
|
||||
elements.length = index;
|
||||
priorities.length = index;
|
||||
this.heapify_();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} key Key.
|
||||
* @return {boolean} Is key queued.
|
||||
*/
|
||||
isKeyQueued(key) {
|
||||
return key in this.queuedElements_;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {T} element Element.
|
||||
* @return {boolean} Is queued.
|
||||
*/
|
||||
isQueued(element) {
|
||||
return this.isKeyQueued(this.keyFunction_(element));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} index The index of the node to move down.
|
||||
* @private
|
||||
*/
|
||||
siftUp_(index) {
|
||||
const elements = this.elements_;
|
||||
const priorities = this.priorities_;
|
||||
const count = elements.length;
|
||||
const element = elements[index];
|
||||
const priority = priorities[index];
|
||||
const startIndex = index;
|
||||
|
||||
while (index < (count >> 1)) {
|
||||
const lIndex = this.getLeftChildIndex_(index);
|
||||
const rIndex = this.getRightChildIndex_(index);
|
||||
|
||||
const smallerChildIndex = rIndex < count &&
|
||||
priorities[rIndex] < priorities[lIndex] ?
|
||||
rIndex : lIndex;
|
||||
|
||||
elements[index] = elements[smallerChildIndex];
|
||||
priorities[index] = priorities[smallerChildIndex];
|
||||
index = smallerChildIndex;
|
||||
}
|
||||
|
||||
elements[index] = element;
|
||||
priorities[index] = priority;
|
||||
this.siftDown_(startIndex, index);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} startIndex The index of the root.
|
||||
* @param {number} index The index of the node to move up.
|
||||
* @private
|
||||
*/
|
||||
siftDown_(startIndex, index) {
|
||||
const elements = this.elements_;
|
||||
const priorities = this.priorities_;
|
||||
const element = elements[index];
|
||||
const priority = priorities[index];
|
||||
|
||||
while (index > startIndex) {
|
||||
const parentIndex = this.getParentIndex_(index);
|
||||
if (priorities[parentIndex] > priority) {
|
||||
elements[index] = elements[parentIndex];
|
||||
priorities[index] = priorities[parentIndex];
|
||||
index = parentIndex;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
elements[index] = element;
|
||||
priorities[index] = priority;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* FIXME empty description for jsdoc
|
||||
*/
|
||||
reprioritize() {
|
||||
const priorityFunction = this.priorityFunction_;
|
||||
const elements = this.elements_;
|
||||
const priorities = this.priorities_;
|
||||
let index = 0;
|
||||
const n = elements.length;
|
||||
let element, i, priority;
|
||||
for (i = 0; i < n; ++i) {
|
||||
element = elements[i];
|
||||
priority = priorityFunction(element);
|
||||
if (priority == DROP) {
|
||||
delete this.queuedElements_[this.keyFunction_(element)];
|
||||
} else {
|
||||
priorities[index] = priority;
|
||||
elements[index++] = element;
|
||||
}
|
||||
}
|
||||
elements.length = index;
|
||||
priorities.length = index;
|
||||
this.heapify_();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export default PriorityQueue;
|
||||
|
||||
@@ -24,55 +24,31 @@ import {isEmpty} from '../obj.js';
|
||||
* @struct
|
||||
* @template T
|
||||
*/
|
||||
const RBush = function(opt_maxEntries) {
|
||||
class RBush {
|
||||
|
||||
constructor(opt_maxEntries) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
this.rbush_ = rbush(opt_maxEntries, undefined);
|
||||
|
||||
/**
|
||||
* A mapping between the objects added to this rbush wrapper
|
||||
* and the objects that are actually added to the internal rbush.
|
||||
* @private
|
||||
* @type {Object.<number, module:ol/structs/RBush~Entry>}
|
||||
*/
|
||||
this.items_ = {};
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* Insert a value into the RBush.
|
||||
* @param {module:ol/extent~Extent} extent Extent.
|
||||
* @param {T} value Value.
|
||||
*/
|
||||
this.rbush_ = rbush(opt_maxEntries, undefined);
|
||||
|
||||
/**
|
||||
* A mapping between the objects added to this rbush wrapper
|
||||
* and the objects that are actually added to the internal rbush.
|
||||
* @private
|
||||
* @type {Object.<number, module:ol/structs/RBush~Entry>}
|
||||
*/
|
||||
this.items_ = {};
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Insert a value into the RBush.
|
||||
* @param {module:ol/extent~Extent} extent Extent.
|
||||
* @param {T} value Value.
|
||||
*/
|
||||
RBush.prototype.insert = function(extent, value) {
|
||||
/** @type {module:ol/structs/RBush~Entry} */
|
||||
const item = {
|
||||
minX: extent[0],
|
||||
minY: extent[1],
|
||||
maxX: extent[2],
|
||||
maxY: extent[3],
|
||||
value: value
|
||||
};
|
||||
|
||||
this.rbush_.insert(item);
|
||||
this.items_[getUid(value)] = item;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Bulk-insert values into the RBush.
|
||||
* @param {Array.<module:ol/extent~Extent>} extents Extents.
|
||||
* @param {Array.<T>} values Values.
|
||||
*/
|
||||
RBush.prototype.load = function(extents, values) {
|
||||
const items = new Array(values.length);
|
||||
for (let i = 0, l = values.length; i < l; i++) {
|
||||
const extent = extents[i];
|
||||
const value = values[i];
|
||||
|
||||
insert(extent, value) {
|
||||
/** @type {module:ol/structs/RBush~Entry} */
|
||||
const item = {
|
||||
minX: extent[0],
|
||||
@@ -81,158 +57,187 @@ RBush.prototype.load = function(extents, values) {
|
||||
maxY: extent[3],
|
||||
value: value
|
||||
};
|
||||
items[i] = item;
|
||||
|
||||
this.rbush_.insert(item);
|
||||
this.items_[getUid(value)] = item;
|
||||
}
|
||||
this.rbush_.load(items);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Remove a value from the RBush.
|
||||
* @param {T} value Value.
|
||||
* @return {boolean} Removed.
|
||||
*/
|
||||
RBush.prototype.remove = function(value) {
|
||||
const uid = getUid(value);
|
||||
/**
|
||||
* Bulk-insert values into the RBush.
|
||||
* @param {Array.<module:ol/extent~Extent>} extents Extents.
|
||||
* @param {Array.<T>} values Values.
|
||||
*/
|
||||
load(extents, values) {
|
||||
const items = new Array(values.length);
|
||||
for (let i = 0, l = values.length; i < l; i++) {
|
||||
const extent = extents[i];
|
||||
const value = values[i];
|
||||
|
||||
// get the object in which the value was wrapped when adding to the
|
||||
// internal rbush. then use that object to do the removal.
|
||||
const item = this.items_[uid];
|
||||
delete this.items_[uid];
|
||||
return this.rbush_.remove(item) !== null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Update the extent of a value in the RBush.
|
||||
* @param {module:ol/extent~Extent} extent Extent.
|
||||
* @param {T} value Value.
|
||||
*/
|
||||
RBush.prototype.update = function(extent, value) {
|
||||
const item = this.items_[getUid(value)];
|
||||
const bbox = [item.minX, item.minY, item.maxX, item.maxY];
|
||||
if (!equals(bbox, extent)) {
|
||||
this.remove(value);
|
||||
this.insert(extent, value);
|
||||
/** @type {module:ol/structs/RBush~Entry} */
|
||||
const item = {
|
||||
minX: extent[0],
|
||||
minY: extent[1],
|
||||
maxX: extent[2],
|
||||
maxY: extent[3],
|
||||
value: value
|
||||
};
|
||||
items[i] = item;
|
||||
this.items_[getUid(value)] = item;
|
||||
}
|
||||
this.rbush_.load(items);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Return all values in the RBush.
|
||||
* @return {Array.<T>} All.
|
||||
*/
|
||||
RBush.prototype.getAll = function() {
|
||||
const items = this.rbush_.all();
|
||||
return items.map(function(item) {
|
||||
return item.value;
|
||||
});
|
||||
};
|
||||
/**
|
||||
* Remove a value from the RBush.
|
||||
* @param {T} value Value.
|
||||
* @return {boolean} Removed.
|
||||
*/
|
||||
remove(value) {
|
||||
const uid = getUid(value);
|
||||
|
||||
// get the object in which the value was wrapped when adding to the
|
||||
// internal rbush. then use that object to do the removal.
|
||||
const item = this.items_[uid];
|
||||
delete this.items_[uid];
|
||||
return this.rbush_.remove(item) !== null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return all values in the given extent.
|
||||
* @param {module:ol/extent~Extent} extent Extent.
|
||||
* @return {Array.<T>} All in extent.
|
||||
*/
|
||||
RBush.prototype.getInExtent = function(extent) {
|
||||
/** @type {module:ol/structs/RBush~Entry} */
|
||||
const bbox = {
|
||||
minX: extent[0],
|
||||
minY: extent[1],
|
||||
maxX: extent[2],
|
||||
maxY: extent[3]
|
||||
};
|
||||
const items = this.rbush_.search(bbox);
|
||||
return items.map(function(item) {
|
||||
return item.value;
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Calls a callback function with each value in the tree.
|
||||
* If the callback returns a truthy value, this value is returned without
|
||||
* checking the rest of the tree.
|
||||
* @param {function(this: S, T): *} callback Callback.
|
||||
* @param {S=} opt_this The object to use as `this` in `callback`.
|
||||
* @return {*} Callback return value.
|
||||
* @template S
|
||||
*/
|
||||
RBush.prototype.forEach = function(callback, opt_this) {
|
||||
return this.forEach_(this.getAll(), callback, opt_this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Calls a callback function with each value in the provided extent.
|
||||
* @param {module:ol/extent~Extent} extent Extent.
|
||||
* @param {function(this: S, T): *} callback Callback.
|
||||
* @param {S=} opt_this The object to use as `this` in `callback`.
|
||||
* @return {*} Callback return value.
|
||||
* @template S
|
||||
*/
|
||||
RBush.prototype.forEachInExtent = function(extent, callback, opt_this) {
|
||||
return this.forEach_(this.getInExtent(extent), callback, opt_this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {Array.<T>} values Values.
|
||||
* @param {function(this: S, T): *} callback Callback.
|
||||
* @param {S=} opt_this The object to use as `this` in `callback`.
|
||||
* @private
|
||||
* @return {*} Callback return value.
|
||||
* @template S
|
||||
*/
|
||||
RBush.prototype.forEach_ = function(values, callback, opt_this) {
|
||||
let result;
|
||||
for (let i = 0, l = values.length; i < l; i++) {
|
||||
result = callback.call(opt_this, values[i]);
|
||||
if (result) {
|
||||
return result;
|
||||
/**
|
||||
* Update the extent of a value in the RBush.
|
||||
* @param {module:ol/extent~Extent} extent Extent.
|
||||
* @param {T} value Value.
|
||||
*/
|
||||
update(extent, value) {
|
||||
const item = this.items_[getUid(value)];
|
||||
const bbox = [item.minX, item.minY, item.maxX, item.maxY];
|
||||
if (!equals(bbox, extent)) {
|
||||
this.remove(value);
|
||||
this.insert(extent, value);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Is empty.
|
||||
*/
|
||||
RBush.prototype.isEmpty = function() {
|
||||
return isEmpty(this.items_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Remove all values from the RBush.
|
||||
*/
|
||||
RBush.prototype.clear = function() {
|
||||
this.rbush_.clear();
|
||||
this.items_ = {};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {module:ol/extent~Extent=} opt_extent Extent.
|
||||
* @return {module:ol/extent~Extent} Extent.
|
||||
*/
|
||||
RBush.prototype.getExtent = function(opt_extent) {
|
||||
// FIXME add getExtent() to rbush
|
||||
const data = this.rbush_.data;
|
||||
return createOrUpdate(data.minX, data.minY, data.maxX, data.maxY, opt_extent);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {module:ol/structs/RBush} rbush R-Tree.
|
||||
*/
|
||||
RBush.prototype.concat = function(rbush) {
|
||||
this.rbush_.load(rbush.rbush_.all());
|
||||
for (const i in rbush.items_) {
|
||||
this.items_[i | 0] = rbush.items_[i | 0];
|
||||
/**
|
||||
* Return all values in the RBush.
|
||||
* @return {Array.<T>} All.
|
||||
*/
|
||||
getAll() {
|
||||
const items = this.rbush_.all();
|
||||
return items.map(function(item) {
|
||||
return item.value;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Return all values in the given extent.
|
||||
* @param {module:ol/extent~Extent} extent Extent.
|
||||
* @return {Array.<T>} All in extent.
|
||||
*/
|
||||
getInExtent(extent) {
|
||||
/** @type {module:ol/structs/RBush~Entry} */
|
||||
const bbox = {
|
||||
minX: extent[0],
|
||||
minY: extent[1],
|
||||
maxX: extent[2],
|
||||
maxY: extent[3]
|
||||
};
|
||||
const items = this.rbush_.search(bbox);
|
||||
return items.map(function(item) {
|
||||
return item.value;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calls a callback function with each value in the tree.
|
||||
* If the callback returns a truthy value, this value is returned without
|
||||
* checking the rest of the tree.
|
||||
* @param {function(this: S, T): *} callback Callback.
|
||||
* @param {S=} opt_this The object to use as `this` in `callback`.
|
||||
* @return {*} Callback return value.
|
||||
* @template S
|
||||
*/
|
||||
forEach(callback, opt_this) {
|
||||
return this.forEach_(this.getAll(), callback, opt_this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calls a callback function with each value in the provided extent.
|
||||
* @param {module:ol/extent~Extent} extent Extent.
|
||||
* @param {function(this: S, T): *} callback Callback.
|
||||
* @param {S=} opt_this The object to use as `this` in `callback`.
|
||||
* @return {*} Callback return value.
|
||||
* @template S
|
||||
*/
|
||||
forEachInExtent(extent, callback, opt_this) {
|
||||
return this.forEach_(this.getInExtent(extent), callback, opt_this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {Array.<T>} values Values.
|
||||
* @param {function(this: S, T): *} callback Callback.
|
||||
* @param {S=} opt_this The object to use as `this` in `callback`.
|
||||
* @private
|
||||
* @return {*} Callback return value.
|
||||
* @template S
|
||||
*/
|
||||
forEach_(values, callback, opt_this) {
|
||||
let result;
|
||||
for (let i = 0, l = values.length; i < l; i++) {
|
||||
result = callback.call(opt_this, values[i]);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Is empty.
|
||||
*/
|
||||
isEmpty() {
|
||||
return isEmpty(this.items_);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove all values from the RBush.
|
||||
*/
|
||||
clear() {
|
||||
this.rbush_.clear();
|
||||
this.items_ = {};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {module:ol/extent~Extent=} opt_extent Extent.
|
||||
* @return {module:ol/extent~Extent} Extent.
|
||||
*/
|
||||
getExtent(opt_extent) {
|
||||
// FIXME add getExtent() to rbush
|
||||
const data = this.rbush_.data;
|
||||
return createOrUpdate(data.minX, data.minY, data.maxX, data.maxY, opt_extent);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {module:ol/structs/RBush} rbush R-Tree.
|
||||
*/
|
||||
concat(rbush) {
|
||||
this.rbush_.load(rbush.rbush_.all());
|
||||
for (const i in rbush.items_) {
|
||||
this.items_[i | 0] = rbush.items_[i | 0];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export default RBush;
|
||||
|
||||
@@ -38,161 +38,160 @@ import {createCanvasContext2D} from '../dom.js';
|
||||
* edges overlap when being rendered). To avoid this we add a
|
||||
* padding around each image.
|
||||
*/
|
||||
const Atlas = function(size, space) {
|
||||
class Atlas {
|
||||
constructor(size, space) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.space_ = space;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<module:ol/style/Atlas~AtlasBlock>}
|
||||
*/
|
||||
this.emptyBlocks_ = [{x: 0, y: 0, width: size, height: size}];
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Object.<string, module:ol/style/Atlas~AtlasInfo>}
|
||||
*/
|
||||
this.entries_ = {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {CanvasRenderingContext2D}
|
||||
*/
|
||||
this.context_ = createCanvasContext2D(size, size);
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {HTMLCanvasElement}
|
||||
*/
|
||||
this.canvas_ = this.context_.canvas;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} id The identifier of the entry to check.
|
||||
* @return {?module:ol/style/Atlas~AtlasInfo} The atlas info.
|
||||
*/
|
||||
get(id) {
|
||||
return this.entries_[id] || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} id The identifier of the entry to add.
|
||||
* @param {number} width The width.
|
||||
* @param {number} height The height.
|
||||
* @param {function(CanvasRenderingContext2D, number, number)} renderCallback
|
||||
* Called to render the new image onto an atlas image.
|
||||
* @param {Object=} opt_this Value to use as `this` when executing
|
||||
* `renderCallback`.
|
||||
* @return {?module:ol/style/Atlas~AtlasInfo} The position and atlas image for the entry.
|
||||
*/
|
||||
add(id, width, height, renderCallback, opt_this) {
|
||||
for (let i = 0, ii = this.emptyBlocks_.length; i < ii; ++i) {
|
||||
const block = this.emptyBlocks_[i];
|
||||
if (block.width >= width + this.space_ &&
|
||||
block.height >= height + this.space_) {
|
||||
// we found a block that is big enough for our entry
|
||||
const entry = {
|
||||
offsetX: block.x + this.space_,
|
||||
offsetY: block.y + this.space_,
|
||||
image: this.canvas_
|
||||
};
|
||||
this.entries_[id] = entry;
|
||||
|
||||
// render the image on the atlas image
|
||||
renderCallback.call(opt_this, this.context_,
|
||||
block.x + this.space_, block.y + this.space_);
|
||||
|
||||
// split the block after the insertion, either horizontally or vertically
|
||||
this.split_(i, block, width + this.space_, height + this.space_);
|
||||
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
|
||||
// there is no space for the new entry in this atlas
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
* @param {number} index The index of the block.
|
||||
* @param {module:ol/style/Atlas~AtlasBlock} block The block to split.
|
||||
* @param {number} width The width of the entry to insert.
|
||||
* @param {number} height The height of the entry to insert.
|
||||
*/
|
||||
this.space_ = space;
|
||||
split_(index, block, width, height) {
|
||||
const deltaWidth = block.width - width;
|
||||
const deltaHeight = block.height - height;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<module:ol/style/Atlas~AtlasBlock>}
|
||||
*/
|
||||
this.emptyBlocks_ = [{x: 0, y: 0, width: size, height: size}];
|
||||
/** @type {module:ol/style/Atlas~AtlasBlock} */
|
||||
let newBlock1;
|
||||
/** @type {module:ol/style/Atlas~AtlasBlock} */
|
||||
let newBlock2;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Object.<string, module:ol/style/Atlas~AtlasInfo>}
|
||||
*/
|
||||
this.entries_ = {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {CanvasRenderingContext2D}
|
||||
*/
|
||||
this.context_ = createCanvasContext2D(size, size);
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {HTMLCanvasElement}
|
||||
*/
|
||||
this.canvas_ = this.context_.canvas;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} id The identifier of the entry to check.
|
||||
* @return {?module:ol/style/Atlas~AtlasInfo} The atlas info.
|
||||
*/
|
||||
Atlas.prototype.get = function(id) {
|
||||
return this.entries_[id] || null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} id The identifier of the entry to add.
|
||||
* @param {number} width The width.
|
||||
* @param {number} height The height.
|
||||
* @param {function(CanvasRenderingContext2D, number, number)} renderCallback
|
||||
* Called to render the new image onto an atlas image.
|
||||
* @param {Object=} opt_this Value to use as `this` when executing
|
||||
* `renderCallback`.
|
||||
* @return {?module:ol/style/Atlas~AtlasInfo} The position and atlas image for the entry.
|
||||
*/
|
||||
Atlas.prototype.add = function(id, width, height, renderCallback, opt_this) {
|
||||
for (let i = 0, ii = this.emptyBlocks_.length; i < ii; ++i) {
|
||||
const block = this.emptyBlocks_[i];
|
||||
if (block.width >= width + this.space_ &&
|
||||
block.height >= height + this.space_) {
|
||||
// we found a block that is big enough for our entry
|
||||
const entry = {
|
||||
offsetX: block.x + this.space_,
|
||||
offsetY: block.y + this.space_,
|
||||
image: this.canvas_
|
||||
if (deltaWidth > deltaHeight) {
|
||||
// split vertically
|
||||
// block right of the inserted entry
|
||||
newBlock1 = {
|
||||
x: block.x + width,
|
||||
y: block.y,
|
||||
width: block.width - width,
|
||||
height: block.height
|
||||
};
|
||||
this.entries_[id] = entry;
|
||||
|
||||
// render the image on the atlas image
|
||||
renderCallback.call(opt_this, this.context_,
|
||||
block.x + this.space_, block.y + this.space_);
|
||||
// block below the inserted entry
|
||||
newBlock2 = {
|
||||
x: block.x,
|
||||
y: block.y + height,
|
||||
width: width,
|
||||
height: block.height - height
|
||||
};
|
||||
this.updateBlocks_(index, newBlock1, newBlock2);
|
||||
} else {
|
||||
// split horizontally
|
||||
// block right of the inserted entry
|
||||
newBlock1 = {
|
||||
x: block.x + width,
|
||||
y: block.y,
|
||||
width: block.width - width,
|
||||
height: height
|
||||
};
|
||||
|
||||
// split the block after the insertion, either horizontally or vertically
|
||||
this.split_(i, block, width + this.space_, height + this.space_);
|
||||
|
||||
return entry;
|
||||
// block below the inserted entry
|
||||
newBlock2 = {
|
||||
x: block.x,
|
||||
y: block.y + height,
|
||||
width: block.width,
|
||||
height: block.height - height
|
||||
};
|
||||
this.updateBlocks_(index, newBlock1, newBlock2);
|
||||
}
|
||||
}
|
||||
|
||||
// there is no space for the new entry in this atlas
|
||||
return null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {number} index The index of the block.
|
||||
* @param {module:ol/style/Atlas~AtlasBlock} block The block to split.
|
||||
* @param {number} width The width of the entry to insert.
|
||||
* @param {number} height The height of the entry to insert.
|
||||
*/
|
||||
Atlas.prototype.split_ = function(index, block, width, height) {
|
||||
const deltaWidth = block.width - width;
|
||||
const deltaHeight = block.height - height;
|
||||
|
||||
/** @type {module:ol/style/Atlas~AtlasBlock} */
|
||||
let newBlock1;
|
||||
/** @type {module:ol/style/Atlas~AtlasBlock} */
|
||||
let newBlock2;
|
||||
|
||||
if (deltaWidth > deltaHeight) {
|
||||
// split vertically
|
||||
// block right of the inserted entry
|
||||
newBlock1 = {
|
||||
x: block.x + width,
|
||||
y: block.y,
|
||||
width: block.width - width,
|
||||
height: block.height
|
||||
};
|
||||
|
||||
// block below the inserted entry
|
||||
newBlock2 = {
|
||||
x: block.x,
|
||||
y: block.y + height,
|
||||
width: width,
|
||||
height: block.height - height
|
||||
};
|
||||
this.updateBlocks_(index, newBlock1, newBlock2);
|
||||
} else {
|
||||
// split horizontally
|
||||
// block right of the inserted entry
|
||||
newBlock1 = {
|
||||
x: block.x + width,
|
||||
y: block.y,
|
||||
width: block.width - width,
|
||||
height: height
|
||||
};
|
||||
|
||||
// block below the inserted entry
|
||||
newBlock2 = {
|
||||
x: block.x,
|
||||
y: block.y + height,
|
||||
width: block.width,
|
||||
height: block.height - height
|
||||
};
|
||||
this.updateBlocks_(index, newBlock1, newBlock2);
|
||||
/**
|
||||
* Remove the old block and insert new blocks at the same array position.
|
||||
* The new blocks are inserted at the same position, so that splitted
|
||||
* blocks (that are potentially smaller) are filled first.
|
||||
* @private
|
||||
* @param {number} index The index of the block to remove.
|
||||
* @param {module:ol/style/Atlas~AtlasBlock} newBlock1 The 1st block to add.
|
||||
* @param {module:ol/style/Atlas~AtlasBlock} newBlock2 The 2nd block to add.
|
||||
*/
|
||||
updateBlocks_(index, newBlock1, newBlock2) {
|
||||
const args = [index, 1];
|
||||
if (newBlock1.width > 0 && newBlock1.height > 0) {
|
||||
args.push(newBlock1);
|
||||
}
|
||||
if (newBlock2.width > 0 && newBlock2.height > 0) {
|
||||
args.push(newBlock2);
|
||||
}
|
||||
this.emptyBlocks_.splice.apply(this.emptyBlocks_, args);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove the old block and insert new blocks at the same array position.
|
||||
* The new blocks are inserted at the same position, so that splitted
|
||||
* blocks (that are potentially smaller) are filled first.
|
||||
* @private
|
||||
* @param {number} index The index of the block to remove.
|
||||
* @param {module:ol/style/Atlas~AtlasBlock} newBlock1 The 1st block to add.
|
||||
* @param {module:ol/style/Atlas~AtlasBlock} newBlock2 The 2nd block to add.
|
||||
*/
|
||||
Atlas.prototype.updateBlocks_ = function(index, newBlock1, newBlock2) {
|
||||
const args = [index, 1];
|
||||
if (newBlock1.width > 0 && newBlock1.height > 0) {
|
||||
args.push(newBlock1);
|
||||
}
|
||||
if (newBlock2.width > 0 && newBlock2.height > 0) {
|
||||
args.push(newBlock2);
|
||||
}
|
||||
this.emptyBlocks_.splice.apply(this.emptyBlocks_, args);
|
||||
};
|
||||
export default Atlas;
|
||||
|
||||
@@ -58,199 +58,196 @@ const MAX_ATLAS_SIZE = -1;
|
||||
* @api
|
||||
* @param {module:ol/style/AtlasManager~Options=} opt_options Options.
|
||||
*/
|
||||
const AtlasManager = function(opt_options) {
|
||||
class AtlasManager {
|
||||
constructor(opt_options) {
|
||||
|
||||
const options = opt_options || {};
|
||||
const options = opt_options || {};
|
||||
|
||||
/**
|
||||
* The size in pixels of the latest atlas image.
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.currentSize_ = options.initialSize !== undefined ?
|
||||
options.initialSize : INITIAL_ATLAS_SIZE;
|
||||
/**
|
||||
* The size in pixels of the latest atlas image.
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.currentSize_ = options.initialSize !== undefined ?
|
||||
options.initialSize : INITIAL_ATLAS_SIZE;
|
||||
|
||||
/**
|
||||
* The maximum size in pixels of atlas images.
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.maxSize_ = options.maxSize !== undefined ?
|
||||
options.maxSize : MAX_ATLAS_SIZE != -1 ?
|
||||
MAX_ATLAS_SIZE : WEBGL_MAX_TEXTURE_SIZE !== undefined ?
|
||||
WEBGL_MAX_TEXTURE_SIZE : 2048;
|
||||
/**
|
||||
* The maximum size in pixels of atlas images.
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.maxSize_ = options.maxSize !== undefined ?
|
||||
options.maxSize : MAX_ATLAS_SIZE != -1 ?
|
||||
MAX_ATLAS_SIZE : WEBGL_MAX_TEXTURE_SIZE !== undefined ?
|
||||
WEBGL_MAX_TEXTURE_SIZE : 2048;
|
||||
|
||||
/**
|
||||
* The size in pixels between images.
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.space_ = options.space !== undefined ? options.space : 1;
|
||||
/**
|
||||
* The size in pixels between images.
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.space_ = options.space !== undefined ? options.space : 1;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<module:ol/style/Atlas>}
|
||||
*/
|
||||
this.atlases_ = [new Atlas(this.currentSize_, this.space_)];
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<module:ol/style/Atlas>}
|
||||
*/
|
||||
this.atlases_ = [new Atlas(this.currentSize_, this.space_)];
|
||||
|
||||
/**
|
||||
* The size in pixels of the latest atlas image for hit-detection images.
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.currentHitSize_ = this.currentSize_;
|
||||
/**
|
||||
* The size in pixels of the latest atlas image for hit-detection images.
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.currentHitSize_ = this.currentSize_;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<module:ol/style/Atlas>}
|
||||
*/
|
||||
this.hitAtlases_ = [new Atlas(this.currentHitSize_, this.space_)];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} id The identifier of the entry to check.
|
||||
* @return {?module:ol/style/AtlasManager~AtlasManagerInfo} The position and atlas image for the
|
||||
* entry, or `null` if the entry is not part of the atlas manager.
|
||||
*/
|
||||
AtlasManager.prototype.getInfo = function(id) {
|
||||
/** @type {?module:ol/style/Atlas~AtlasInfo} */
|
||||
const info = this.getInfo_(this.atlases_, id);
|
||||
|
||||
if (!info) {
|
||||
return null;
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<module:ol/style/Atlas>}
|
||||
*/
|
||||
this.hitAtlases_ = [new Atlas(this.currentHitSize_, this.space_)];
|
||||
}
|
||||
const hitInfo = /** @type {module:ol/style/Atlas~AtlasInfo} */ (this.getInfo_(this.hitAtlases_, id));
|
||||
|
||||
return this.mergeInfos_(info, hitInfo);
|
||||
};
|
||||
/**
|
||||
* @param {string} id The identifier of the entry to check.
|
||||
* @return {?module:ol/style/AtlasManager~AtlasManagerInfo} The position and atlas image for the
|
||||
* entry, or `null` if the entry is not part of the atlas manager.
|
||||
*/
|
||||
getInfo(id) {
|
||||
/** @type {?module:ol/style/Atlas~AtlasInfo} */
|
||||
const info = this.getInfo_(this.atlases_, id);
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {Array.<module:ol/style/Atlas>} atlases The atlases to search.
|
||||
* @param {string} id The identifier of the entry to check.
|
||||
* @return {?module:ol/style/Atlas~AtlasInfo} The position and atlas image for the entry,
|
||||
* or `null` if the entry is not part of the atlases.
|
||||
*/
|
||||
AtlasManager.prototype.getInfo_ = function(atlases, id) {
|
||||
for (let i = 0, ii = atlases.length; i < ii; ++i) {
|
||||
const atlas = atlases[i];
|
||||
const info = atlas.get(id);
|
||||
if (info) {
|
||||
return info;
|
||||
if (!info) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
const hitInfo = /** @type {module:ol/style/Atlas~AtlasInfo} */ (this.getInfo_(this.hitAtlases_, id));
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {module:ol/style/Atlas~AtlasInfo} info The info for the real image.
|
||||
* @param {module:ol/style/Atlas~AtlasInfo} hitInfo The info for the hit-detection
|
||||
* image.
|
||||
* @return {?module:ol/style/AtlasManager~AtlasManagerInfo} The position and atlas image for the
|
||||
* entry, or `null` if the entry is not part of the atlases.
|
||||
*/
|
||||
AtlasManager.prototype.mergeInfos_ = function(info, hitInfo) {
|
||||
return (
|
||||
/** @type {module:ol/style/AtlasManager~AtlasManagerInfo} */ ({
|
||||
offsetX: info.offsetX,
|
||||
offsetY: info.offsetY,
|
||||
image: info.image,
|
||||
hitImage: hitInfo.image
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Add an image to the atlas manager.
|
||||
*
|
||||
* If an entry for the given id already exists, the entry will
|
||||
* be overridden (but the space on the atlas graphic will not be freed).
|
||||
*
|
||||
* If `renderHitCallback` is provided, the image (or the hit-detection version
|
||||
* of the image) will be rendered into a separate hit-detection atlas image.
|
||||
*
|
||||
* @param {string} id The identifier of the entry to add.
|
||||
* @param {number} width The width.
|
||||
* @param {number} height The height.
|
||||
* @param {function(CanvasRenderingContext2D, number, number)} renderCallback
|
||||
* Called to render the new image onto an atlas image.
|
||||
* @param {function(CanvasRenderingContext2D, number, number)=}
|
||||
* opt_renderHitCallback Called to render a hit-detection image onto a hit
|
||||
* detection atlas image.
|
||||
* @param {Object=} opt_this Value to use as `this` when executing
|
||||
* `renderCallback` and `renderHitCallback`.
|
||||
* @return {?module:ol/style/AtlasManager~AtlasManagerInfo} The position and atlas image for the
|
||||
* entry, or `null` if the image is too big.
|
||||
*/
|
||||
AtlasManager.prototype.add = function(id, width, height,
|
||||
renderCallback, opt_renderHitCallback, opt_this) {
|
||||
if (width + this.space_ > this.maxSize_ ||
|
||||
height + this.space_ > this.maxSize_) {
|
||||
return null;
|
||||
return this.mergeInfos_(info, hitInfo);
|
||||
}
|
||||
|
||||
/** @type {?module:ol/style/Atlas~AtlasInfo} */
|
||||
const info = this.add_(false, id, width, height, renderCallback, opt_this);
|
||||
if (!info) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// even if no hit-detection entry is requested, we insert a fake entry into
|
||||
// the hit-detection atlas, to make sure that the offset is the same for
|
||||
// the original image and the hit-detection image.
|
||||
const renderHitCallback = opt_renderHitCallback !== undefined ?
|
||||
opt_renderHitCallback : UNDEFINED;
|
||||
|
||||
const hitInfo = /** @type {module:ol/style/Atlas~AtlasInfo} */ (this.add_(true,
|
||||
id, width, height, renderHitCallback, opt_this));
|
||||
|
||||
return this.mergeInfos_(info, hitInfo);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {boolean} isHitAtlas If the hit-detection atlases are used.
|
||||
* @param {string} id The identifier of the entry to add.
|
||||
* @param {number} width The width.
|
||||
* @param {number} height The height.
|
||||
* @param {function(CanvasRenderingContext2D, number, number)} renderCallback
|
||||
* Called to render the new image onto an atlas image.
|
||||
* @param {Object=} opt_this Value to use as `this` when executing
|
||||
* `renderCallback` and `renderHitCallback`.
|
||||
* @return {?module:ol/style/Atlas~AtlasInfo} The position and atlas image for the entry,
|
||||
* or `null` if the image is too big.
|
||||
*/
|
||||
AtlasManager.prototype.add_ = function(isHitAtlas, id, width, height, renderCallback, opt_this) {
|
||||
const atlases = (isHitAtlas) ? this.hitAtlases_ : this.atlases_;
|
||||
let atlas, info, i, ii;
|
||||
for (i = 0, ii = atlases.length; i < ii; ++i) {
|
||||
atlas = atlases[i];
|
||||
info = atlas.add(id, width, height, renderCallback, opt_this);
|
||||
if (info) {
|
||||
return info;
|
||||
} else if (!info && i === ii - 1) {
|
||||
// the entry could not be added to one of the existing atlases,
|
||||
// create a new atlas that is twice as big and try to add to this one.
|
||||
let size;
|
||||
if (isHitAtlas) {
|
||||
size = Math.min(this.currentHitSize_ * 2, this.maxSize_);
|
||||
this.currentHitSize_ = size;
|
||||
} else {
|
||||
size = Math.min(this.currentSize_ * 2, this.maxSize_);
|
||||
this.currentSize_ = size;
|
||||
/**
|
||||
* @private
|
||||
* @param {Array.<module:ol/style/Atlas>} atlases The atlases to search.
|
||||
* @param {string} id The identifier of the entry to check.
|
||||
* @return {?module:ol/style/Atlas~AtlasInfo} The position and atlas image for the entry,
|
||||
* or `null` if the entry is not part of the atlases.
|
||||
*/
|
||||
getInfo_(atlases, id) {
|
||||
for (let i = 0, ii = atlases.length; i < ii; ++i) {
|
||||
const atlas = atlases[i];
|
||||
const info = atlas.get(id);
|
||||
if (info) {
|
||||
return info;
|
||||
}
|
||||
atlas = new Atlas(size, this.space_);
|
||||
atlases.push(atlas);
|
||||
// run the loop another time
|
||||
++ii;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {module:ol/style/Atlas~AtlasInfo} info The info for the real image.
|
||||
* @param {module:ol/style/Atlas~AtlasInfo} hitInfo The info for the hit-detection
|
||||
* image.
|
||||
* @return {?module:ol/style/AtlasManager~AtlasManagerInfo} The position and atlas image for the
|
||||
* entry, or `null` if the entry is not part of the atlases.
|
||||
*/
|
||||
mergeInfos_(info, hitInfo) {
|
||||
return (
|
||||
/** @type {module:ol/style/AtlasManager~AtlasManagerInfo} */ ({
|
||||
offsetX: info.offsetX,
|
||||
offsetY: info.offsetY,
|
||||
image: info.image,
|
||||
hitImage: hitInfo.image
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an image to the atlas manager.
|
||||
*
|
||||
* If an entry for the given id already exists, the entry will
|
||||
* be overridden (but the space on the atlas graphic will not be freed).
|
||||
*
|
||||
* If `renderHitCallback` is provided, the image (or the hit-detection version
|
||||
* of the image) will be rendered into a separate hit-detection atlas image.
|
||||
*
|
||||
* @param {string} id The identifier of the entry to add.
|
||||
* @param {number} width The width.
|
||||
* @param {number} height The height.
|
||||
* @param {function(CanvasRenderingContext2D, number, number)} renderCallback
|
||||
* Called to render the new image onto an atlas image.
|
||||
* @param {function(CanvasRenderingContext2D, number, number)=}
|
||||
* opt_renderHitCallback Called to render a hit-detection image onto a hit
|
||||
* detection atlas image.
|
||||
* @param {Object=} opt_this Value to use as `this` when executing
|
||||
* `renderCallback` and `renderHitCallback`.
|
||||
* @return {?module:ol/style/AtlasManager~AtlasManagerInfo} The position and atlas image for the
|
||||
* entry, or `null` if the image is too big.
|
||||
*/
|
||||
add(id, width, height, renderCallback, opt_renderHitCallback, opt_this) {
|
||||
if (width + this.space_ > this.maxSize_ ||
|
||||
height + this.space_ > this.maxSize_) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @type {?module:ol/style/Atlas~AtlasInfo} */
|
||||
const info = this.add_(false, id, width, height, renderCallback, opt_this);
|
||||
if (!info) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// even if no hit-detection entry is requested, we insert a fake entry into
|
||||
// the hit-detection atlas, to make sure that the offset is the same for
|
||||
// the original image and the hit-detection image.
|
||||
const renderHitCallback = opt_renderHitCallback !== undefined ?
|
||||
opt_renderHitCallback : UNDEFINED;
|
||||
|
||||
const hitInfo = /** @type {module:ol/style/Atlas~AtlasInfo} */ (this.add_(true,
|
||||
id, width, height, renderHitCallback, opt_this));
|
||||
|
||||
return this.mergeInfos_(info, hitInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {boolean} isHitAtlas If the hit-detection atlases are used.
|
||||
* @param {string} id The identifier of the entry to add.
|
||||
* @param {number} width The width.
|
||||
* @param {number} height The height.
|
||||
* @param {function(CanvasRenderingContext2D, number, number)} renderCallback
|
||||
* Called to render the new image onto an atlas image.
|
||||
* @param {Object=} opt_this Value to use as `this` when executing
|
||||
* `renderCallback` and `renderHitCallback`.
|
||||
* @return {?module:ol/style/Atlas~AtlasInfo} The position and atlas image for the entry,
|
||||
* or `null` if the image is too big.
|
||||
*/
|
||||
add_(isHitAtlas, id, width, height, renderCallback, opt_this) {
|
||||
const atlases = (isHitAtlas) ? this.hitAtlases_ : this.atlases_;
|
||||
let atlas, info, i, ii;
|
||||
for (i = 0, ii = atlases.length; i < ii; ++i) {
|
||||
atlas = atlases[i];
|
||||
info = atlas.add(id, width, height, renderCallback, opt_this);
|
||||
if (info) {
|
||||
return info;
|
||||
} else if (!info && i === ii - 1) {
|
||||
// the entry could not be added to one of the existing atlases,
|
||||
// create a new atlas that is twice as big and try to add to this one.
|
||||
let size;
|
||||
if (isHitAtlas) {
|
||||
size = Math.min(this.currentHitSize_ * 2, this.maxSize_);
|
||||
this.currentHitSize_ = size;
|
||||
} else {
|
||||
size = Math.min(this.currentSize_ * 2, this.maxSize_);
|
||||
this.currentSize_ = size;
|
||||
}
|
||||
atlas = new Atlas(size, this.space_);
|
||||
atlases.push(atlas);
|
||||
// run the loop another time
|
||||
++ii;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export default AtlasManager;
|
||||
|
||||
@@ -29,52 +29,54 @@ import RegularShape from '../style/RegularShape.js';
|
||||
* @extends {module:ol/style/RegularShape}
|
||||
* @api
|
||||
*/
|
||||
const CircleStyle = function(opt_options) {
|
||||
class CircleStyle {
|
||||
constructor(opt_options) {
|
||||
|
||||
const options = opt_options || {};
|
||||
const options = opt_options || {};
|
||||
|
||||
RegularShape.call(this, {
|
||||
points: Infinity,
|
||||
fill: options.fill,
|
||||
radius: options.radius,
|
||||
snapToPixel: options.snapToPixel,
|
||||
stroke: options.stroke,
|
||||
atlasManager: options.atlasManager
|
||||
});
|
||||
RegularShape.call(this, {
|
||||
points: Infinity,
|
||||
fill: options.fill,
|
||||
radius: options.radius,
|
||||
snapToPixel: options.snapToPixel,
|
||||
stroke: options.stroke,
|
||||
atlasManager: options.atlasManager
|
||||
});
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Clones the style. If an atlasmanager was provided to the original style it will be used in the cloned style, too.
|
||||
* @return {module:ol/style/Circle} The cloned style.
|
||||
* @override
|
||||
* @api
|
||||
*/
|
||||
clone() {
|
||||
const style = new CircleStyle({
|
||||
fill: this.getFill() ? this.getFill().clone() : undefined,
|
||||
stroke: this.getStroke() ? this.getStroke().clone() : undefined,
|
||||
radius: this.getRadius(),
|
||||
snapToPixel: this.getSnapToPixel(),
|
||||
atlasManager: this.atlasManager_
|
||||
});
|
||||
style.setOpacity(this.getOpacity());
|
||||
style.setScale(this.getScale());
|
||||
return style;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the circle radius.
|
||||
*
|
||||
* @param {number} radius Circle radius.
|
||||
* @api
|
||||
*/
|
||||
setRadius(radius) {
|
||||
this.radius_ = radius;
|
||||
this.render_(this.atlasManager_);
|
||||
}
|
||||
}
|
||||
|
||||
inherits(CircleStyle, RegularShape);
|
||||
|
||||
|
||||
/**
|
||||
* Clones the style. If an atlasmanager was provided to the original style it will be used in the cloned style, too.
|
||||
* @return {module:ol/style/Circle} The cloned style.
|
||||
* @override
|
||||
* @api
|
||||
*/
|
||||
CircleStyle.prototype.clone = function() {
|
||||
const style = new CircleStyle({
|
||||
fill: this.getFill() ? this.getFill().clone() : undefined,
|
||||
stroke: this.getStroke() ? this.getStroke().clone() : undefined,
|
||||
radius: this.getRadius(),
|
||||
snapToPixel: this.getSnapToPixel(),
|
||||
atlasManager: this.atlasManager_
|
||||
});
|
||||
style.setOpacity(this.getOpacity());
|
||||
style.setScale(this.getScale());
|
||||
return style;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the circle radius.
|
||||
*
|
||||
* @param {number} radius Circle radius.
|
||||
* @api
|
||||
*/
|
||||
CircleStyle.prototype.setRadius = function(radius) {
|
||||
this.radius_ = radius;
|
||||
this.render_(this.atlasManager_);
|
||||
};
|
||||
export default CircleStyle;
|
||||
|
||||
@@ -21,74 +21,73 @@ import {asString} from '../color.js';
|
||||
* @param {module:ol/style/Fill~Options=} opt_options Options.
|
||||
* @api
|
||||
*/
|
||||
const Fill = function(opt_options) {
|
||||
class Fill {
|
||||
constructor(opt_options) {
|
||||
|
||||
const options = opt_options || {};
|
||||
const options = opt_options || {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/color~Color|module:ol/colorlike~ColorLike}
|
||||
*/
|
||||
this.color_ = options.color !== undefined ? options.color : null;
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/color~Color|module:ol/colorlike~ColorLike}
|
||||
*/
|
||||
this.color_ = options.color !== undefined ? options.color : null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {string|undefined}
|
||||
*/
|
||||
this.checksum_ = undefined;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Clones the style. The color is not cloned if it is an {@link module:ol/colorlike~ColorLike}.
|
||||
* @return {module:ol/style/Fill} The cloned style.
|
||||
* @api
|
||||
*/
|
||||
Fill.prototype.clone = function() {
|
||||
const color = this.getColor();
|
||||
return new Fill({
|
||||
color: (color && color.slice) ? color.slice() : color || undefined
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the fill color.
|
||||
* @return {module:ol/color~Color|module:ol/colorlike~ColorLike} Color.
|
||||
* @api
|
||||
*/
|
||||
Fill.prototype.getColor = function() {
|
||||
return this.color_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the color.
|
||||
*
|
||||
* @param {module:ol/color~Color|module:ol/colorlike~ColorLike} color Color.
|
||||
* @api
|
||||
*/
|
||||
Fill.prototype.setColor = function(color) {
|
||||
this.color_ = color;
|
||||
this.checksum_ = undefined;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {string} The checksum.
|
||||
*/
|
||||
Fill.prototype.getChecksum = function() {
|
||||
if (this.checksum_ === undefined) {
|
||||
if (
|
||||
this.color_ instanceof CanvasPattern ||
|
||||
this.color_ instanceof CanvasGradient
|
||||
) {
|
||||
this.checksum_ = getUid(this.color_).toString();
|
||||
} else {
|
||||
this.checksum_ = 'f' + (this.color_ ? asString(this.color_) : '-');
|
||||
}
|
||||
/**
|
||||
* @private
|
||||
* @type {string|undefined}
|
||||
*/
|
||||
this.checksum_ = undefined;
|
||||
}
|
||||
|
||||
return this.checksum_;
|
||||
};
|
||||
/**
|
||||
* Clones the style. The color is not cloned if it is an {@link module:ol/colorlike~ColorLike}.
|
||||
* @return {module:ol/style/Fill} The cloned style.
|
||||
* @api
|
||||
*/
|
||||
clone() {
|
||||
const color = this.getColor();
|
||||
return new Fill({
|
||||
color: (color && color.slice) ? color.slice() : color || undefined
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the fill color.
|
||||
* @return {module:ol/color~Color|module:ol/colorlike~ColorLike} Color.
|
||||
* @api
|
||||
*/
|
||||
getColor() {
|
||||
return this.color_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the color.
|
||||
*
|
||||
* @param {module:ol/color~Color|module:ol/colorlike~ColorLike} color Color.
|
||||
* @api
|
||||
*/
|
||||
setColor(color) {
|
||||
this.color_ = color;
|
||||
this.checksum_ = undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {string} The checksum.
|
||||
*/
|
||||
getChecksum() {
|
||||
if (this.checksum_ === undefined) {
|
||||
if (
|
||||
this.color_ instanceof CanvasPattern ||
|
||||
this.color_ instanceof CanvasGradient
|
||||
) {
|
||||
this.checksum_ = getUid(this.color_).toString();
|
||||
} else {
|
||||
this.checksum_ = 'f' + (this.color_ ? asString(this.color_) : '-');
|
||||
}
|
||||
}
|
||||
|
||||
return this.checksum_;
|
||||
}
|
||||
}
|
||||
|
||||
export default Fill;
|
||||
|
||||
@@ -61,374 +61,364 @@ import ImageStyle from '../style/Image.js';
|
||||
* @extends {module:ol/style/Image}
|
||||
* @api
|
||||
*/
|
||||
const Icon = function(opt_options) {
|
||||
class Icon {
|
||||
constructor(opt_options) {
|
||||
|
||||
const options = opt_options || {};
|
||||
const options = opt_options || {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<number>}
|
||||
*/
|
||||
this.anchor_ = options.anchor !== undefined ? options.anchor : [0.5, 0.5];
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<number>}
|
||||
*/
|
||||
this.anchor_ = options.anchor !== undefined ? options.anchor : [0.5, 0.5];
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<number>}
|
||||
*/
|
||||
this.normalizedAnchor_ = null;
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<number>}
|
||||
*/
|
||||
this.normalizedAnchor_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/style/IconOrigin}
|
||||
*/
|
||||
this.anchorOrigin_ = options.anchorOrigin !== undefined ?
|
||||
options.anchorOrigin : IconOrigin.TOP_LEFT;
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/style/IconOrigin}
|
||||
*/
|
||||
this.anchorOrigin_ = options.anchorOrigin !== undefined ?
|
||||
options.anchorOrigin : IconOrigin.TOP_LEFT;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/style/IconAnchorUnits}
|
||||
*/
|
||||
this.anchorXUnits_ = options.anchorXUnits !== undefined ?
|
||||
options.anchorXUnits : IconAnchorUnits.FRACTION;
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/style/IconAnchorUnits}
|
||||
*/
|
||||
this.anchorXUnits_ = options.anchorXUnits !== undefined ?
|
||||
options.anchorXUnits : IconAnchorUnits.FRACTION;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/style/IconAnchorUnits}
|
||||
*/
|
||||
this.anchorYUnits_ = options.anchorYUnits !== undefined ?
|
||||
options.anchorYUnits : IconAnchorUnits.FRACTION;
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/style/IconAnchorUnits}
|
||||
*/
|
||||
this.anchorYUnits_ = options.anchorYUnits !== undefined ?
|
||||
options.anchorYUnits : IconAnchorUnits.FRACTION;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {?string}
|
||||
*/
|
||||
this.crossOrigin_ =
|
||||
options.crossOrigin !== undefined ? options.crossOrigin : null;
|
||||
/**
|
||||
* @private
|
||||
* @type {?string}
|
||||
*/
|
||||
this.crossOrigin_ =
|
||||
options.crossOrigin !== undefined ? options.crossOrigin : null;
|
||||
|
||||
/**
|
||||
* @type {HTMLImageElement|HTMLCanvasElement}
|
||||
*/
|
||||
const image = options.img !== undefined ? options.img : null;
|
||||
/**
|
||||
* @type {HTMLImageElement|HTMLCanvasElement}
|
||||
*/
|
||||
const image = options.img !== undefined ? options.img : null;
|
||||
|
||||
/**
|
||||
* @type {module:ol/size~Size}
|
||||
*/
|
||||
const imgSize = options.imgSize !== undefined ? options.imgSize : null;
|
||||
/**
|
||||
* @type {module:ol/size~Size}
|
||||
*/
|
||||
const imgSize = options.imgSize !== undefined ? options.imgSize : null;
|
||||
|
||||
/**
|
||||
* @type {string|undefined}
|
||||
*/
|
||||
let src = options.src;
|
||||
/**
|
||||
* @type {string|undefined}
|
||||
*/
|
||||
let src = options.src;
|
||||
|
||||
assert(!(src !== undefined && image),
|
||||
4); // `image` and `src` cannot be provided at the same time
|
||||
assert(!image || (image && imgSize),
|
||||
5); // `imgSize` must be set when `image` is provided
|
||||
assert(!(src !== undefined && image),
|
||||
4); // `image` and `src` cannot be provided at the same time
|
||||
assert(!image || (image && imgSize),
|
||||
5); // `imgSize` must be set when `image` is provided
|
||||
|
||||
if ((src === undefined || src.length === 0) && image) {
|
||||
src = image.src || getUid(image).toString();
|
||||
}
|
||||
assert(src !== undefined && src.length > 0,
|
||||
6); // A defined and non-empty `src` or `image` must be provided
|
||||
|
||||
/**
|
||||
* @type {module:ol/ImageState}
|
||||
*/
|
||||
const imageState = options.src !== undefined ?
|
||||
ImageState.IDLE : ImageState.LOADED;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/color~Color}
|
||||
*/
|
||||
this.color_ = options.color !== undefined ? asArray(options.color) : null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/style/IconImage}
|
||||
*/
|
||||
this.iconImage_ = getIconImage(
|
||||
image, /** @type {string} */ (src), imgSize, this.crossOrigin_, imageState, this.color_);
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<number>}
|
||||
*/
|
||||
this.offset_ = options.offset !== undefined ? options.offset : [0, 0];
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/style/IconOrigin}
|
||||
*/
|
||||
this.offsetOrigin_ = options.offsetOrigin !== undefined ?
|
||||
options.offsetOrigin : IconOrigin.TOP_LEFT;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<number>}
|
||||
*/
|
||||
this.origin_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/size~Size}
|
||||
*/
|
||||
this.size_ = options.size !== undefined ? options.size : null;
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
const opacity = options.opacity !== undefined ? options.opacity : 1;
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
const rotateWithView = options.rotateWithView !== undefined ?
|
||||
options.rotateWithView : false;
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
const rotation = options.rotation !== undefined ? options.rotation : 0;
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
const scale = options.scale !== undefined ? options.scale : 1;
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
const snapToPixel = options.snapToPixel !== undefined ?
|
||||
options.snapToPixel : true;
|
||||
|
||||
ImageStyle.call(this, {
|
||||
opacity: opacity,
|
||||
rotation: rotation,
|
||||
scale: scale,
|
||||
snapToPixel: snapToPixel,
|
||||
rotateWithView: rotateWithView
|
||||
});
|
||||
|
||||
if ((src === undefined || src.length === 0) && image) {
|
||||
src = image.src || getUid(image).toString();
|
||||
}
|
||||
assert(src !== undefined && src.length > 0,
|
||||
6); // A defined and non-empty `src` or `image` must be provided
|
||||
|
||||
/**
|
||||
* @type {module:ol/ImageState}
|
||||
* Clones the style. The underlying Image/HTMLCanvasElement is not cloned.
|
||||
* @return {module:ol/style/Icon} The cloned style.
|
||||
* @api
|
||||
*/
|
||||
const imageState = options.src !== undefined ?
|
||||
ImageState.IDLE : ImageState.LOADED;
|
||||
clone() {
|
||||
return new Icon({
|
||||
anchor: this.anchor_.slice(),
|
||||
anchorOrigin: this.anchorOrigin_,
|
||||
anchorXUnits: this.anchorXUnits_,
|
||||
anchorYUnits: this.anchorYUnits_,
|
||||
crossOrigin: this.crossOrigin_,
|
||||
color: (this.color_ && this.color_.slice) ? this.color_.slice() : this.color_ || undefined,
|
||||
src: this.getSrc(),
|
||||
offset: this.offset_.slice(),
|
||||
offsetOrigin: this.offsetOrigin_,
|
||||
size: this.size_ !== null ? this.size_.slice() : undefined,
|
||||
opacity: this.getOpacity(),
|
||||
scale: this.getScale(),
|
||||
snapToPixel: this.getSnapToPixel(),
|
||||
rotation: this.getRotation(),
|
||||
rotateWithView: this.getRotateWithView()
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/color~Color}
|
||||
* @inheritDoc
|
||||
* @api
|
||||
*/
|
||||
this.color_ = options.color !== undefined ? asArray(options.color) : null;
|
||||
getAnchor() {
|
||||
if (this.normalizedAnchor_) {
|
||||
return this.normalizedAnchor_;
|
||||
}
|
||||
let anchor = this.anchor_;
|
||||
const size = this.getSize();
|
||||
if (this.anchorXUnits_ == IconAnchorUnits.FRACTION ||
|
||||
this.anchorYUnits_ == IconAnchorUnits.FRACTION) {
|
||||
if (!size) {
|
||||
return null;
|
||||
}
|
||||
anchor = this.anchor_.slice();
|
||||
if (this.anchorXUnits_ == IconAnchorUnits.FRACTION) {
|
||||
anchor[0] *= size[0];
|
||||
}
|
||||
if (this.anchorYUnits_ == IconAnchorUnits.FRACTION) {
|
||||
anchor[1] *= size[1];
|
||||
}
|
||||
}
|
||||
|
||||
if (this.anchorOrigin_ != IconOrigin.TOP_LEFT) {
|
||||
if (!size) {
|
||||
return null;
|
||||
}
|
||||
if (anchor === this.anchor_) {
|
||||
anchor = this.anchor_.slice();
|
||||
}
|
||||
if (this.anchorOrigin_ == IconOrigin.TOP_RIGHT ||
|
||||
this.anchorOrigin_ == IconOrigin.BOTTOM_RIGHT) {
|
||||
anchor[0] = -anchor[0] + size[0];
|
||||
}
|
||||
if (this.anchorOrigin_ == IconOrigin.BOTTOM_LEFT ||
|
||||
this.anchorOrigin_ == IconOrigin.BOTTOM_RIGHT) {
|
||||
anchor[1] = -anchor[1] + size[1];
|
||||
}
|
||||
}
|
||||
this.normalizedAnchor_ = anchor;
|
||||
return this.normalizedAnchor_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/style/IconImage}
|
||||
* Set the anchor point. The anchor determines the center point for the
|
||||
* symbolizer.
|
||||
*
|
||||
* @param {Array.<number>} anchor Anchor.
|
||||
* @api
|
||||
*/
|
||||
this.iconImage_ = getIconImage(
|
||||
image, /** @type {string} */ (src), imgSize, this.crossOrigin_, imageState, this.color_);
|
||||
setAnchor(anchor) {
|
||||
this.anchor_ = anchor;
|
||||
this.normalizedAnchor_ = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<number>}
|
||||
* Get the icon color.
|
||||
* @return {module:ol/color~Color} Color.
|
||||
* @api
|
||||
*/
|
||||
this.offset_ = options.offset !== undefined ? options.offset : [0, 0];
|
||||
getColor() {
|
||||
return this.color_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/style/IconOrigin}
|
||||
* Get the image icon.
|
||||
* @param {number} pixelRatio Pixel ratio.
|
||||
* @return {HTMLImageElement|HTMLCanvasElement} Image or Canvas element.
|
||||
* @override
|
||||
* @api
|
||||
*/
|
||||
this.offsetOrigin_ = options.offsetOrigin !== undefined ?
|
||||
options.offsetOrigin : IconOrigin.TOP_LEFT;
|
||||
getImage(pixelRatio) {
|
||||
return this.iconImage_.getImage(pixelRatio);
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<number>}
|
||||
* @override
|
||||
*/
|
||||
this.origin_ = null;
|
||||
getImageSize() {
|
||||
return this.iconImage_.getSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/size~Size}
|
||||
* @override
|
||||
*/
|
||||
this.size_ = options.size !== undefined ? options.size : null;
|
||||
getHitDetectionImageSize() {
|
||||
return this.getImageSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
* @override
|
||||
*/
|
||||
const opacity = options.opacity !== undefined ? options.opacity : 1;
|
||||
getImageState() {
|
||||
return this.iconImage_.getImageState();
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
* @override
|
||||
*/
|
||||
const rotateWithView = options.rotateWithView !== undefined ?
|
||||
options.rotateWithView : false;
|
||||
getHitDetectionImage(pixelRatio) {
|
||||
return this.iconImage_.getHitDetectionImage(pixelRatio);
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
* @inheritDoc
|
||||
* @api
|
||||
*/
|
||||
const rotation = options.rotation !== undefined ? options.rotation : 0;
|
||||
getOrigin() {
|
||||
if (this.origin_) {
|
||||
return this.origin_;
|
||||
}
|
||||
let offset = this.offset_;
|
||||
|
||||
if (this.offsetOrigin_ != IconOrigin.TOP_LEFT) {
|
||||
const size = this.getSize();
|
||||
const iconImageSize = this.iconImage_.getSize();
|
||||
if (!size || !iconImageSize) {
|
||||
return null;
|
||||
}
|
||||
offset = offset.slice();
|
||||
if (this.offsetOrigin_ == IconOrigin.TOP_RIGHT ||
|
||||
this.offsetOrigin_ == IconOrigin.BOTTOM_RIGHT) {
|
||||
offset[0] = iconImageSize[0] - size[0] - offset[0];
|
||||
}
|
||||
if (this.offsetOrigin_ == IconOrigin.BOTTOM_LEFT ||
|
||||
this.offsetOrigin_ == IconOrigin.BOTTOM_RIGHT) {
|
||||
offset[1] = iconImageSize[1] - size[1] - offset[1];
|
||||
}
|
||||
}
|
||||
this.origin_ = offset;
|
||||
return this.origin_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
* Get the image URL.
|
||||
* @return {string|undefined} Image src.
|
||||
* @api
|
||||
*/
|
||||
const scale = options.scale !== undefined ? options.scale : 1;
|
||||
getSrc() {
|
||||
return this.iconImage_.getSrc();
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
* @inheritDoc
|
||||
* @api
|
||||
*/
|
||||
const snapToPixel = options.snapToPixel !== undefined ?
|
||||
options.snapToPixel : true;
|
||||
getSize() {
|
||||
return !this.size_ ? this.iconImage_.getSize() : this.size_;
|
||||
}
|
||||
|
||||
ImageStyle.call(this, {
|
||||
opacity: opacity,
|
||||
rotation: rotation,
|
||||
scale: scale,
|
||||
snapToPixel: snapToPixel,
|
||||
rotateWithView: rotateWithView
|
||||
});
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
listenImageChange(listener, thisArg) {
|
||||
return listen(this.iconImage_, EventType.CHANGE,
|
||||
listener, thisArg);
|
||||
}
|
||||
|
||||
};
|
||||
/**
|
||||
* Load not yet loaded URI.
|
||||
* When rendering a feature with an icon style, the vector renderer will
|
||||
* automatically call this method. However, you might want to call this
|
||||
* method yourself for preloading or other purposes.
|
||||
* @override
|
||||
* @api
|
||||
*/
|
||||
load() {
|
||||
this.iconImage_.load();
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
unlistenImageChange(listener, thisArg) {
|
||||
unlisten(this.iconImage_, EventType.CHANGE,
|
||||
listener, thisArg);
|
||||
}
|
||||
}
|
||||
|
||||
inherits(Icon, ImageStyle);
|
||||
|
||||
|
||||
/**
|
||||
* Clones the style. The underlying Image/HTMLCanvasElement is not cloned.
|
||||
* @return {module:ol/style/Icon} The cloned style.
|
||||
* @api
|
||||
*/
|
||||
Icon.prototype.clone = function() {
|
||||
return new Icon({
|
||||
anchor: this.anchor_.slice(),
|
||||
anchorOrigin: this.anchorOrigin_,
|
||||
anchorXUnits: this.anchorXUnits_,
|
||||
anchorYUnits: this.anchorYUnits_,
|
||||
crossOrigin: this.crossOrigin_,
|
||||
color: (this.color_ && this.color_.slice) ? this.color_.slice() : this.color_ || undefined,
|
||||
src: this.getSrc(),
|
||||
offset: this.offset_.slice(),
|
||||
offsetOrigin: this.offsetOrigin_,
|
||||
size: this.size_ !== null ? this.size_.slice() : undefined,
|
||||
opacity: this.getOpacity(),
|
||||
scale: this.getScale(),
|
||||
snapToPixel: this.getSnapToPixel(),
|
||||
rotation: this.getRotation(),
|
||||
rotateWithView: this.getRotateWithView()
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @api
|
||||
*/
|
||||
Icon.prototype.getAnchor = function() {
|
||||
if (this.normalizedAnchor_) {
|
||||
return this.normalizedAnchor_;
|
||||
}
|
||||
let anchor = this.anchor_;
|
||||
const size = this.getSize();
|
||||
if (this.anchorXUnits_ == IconAnchorUnits.FRACTION ||
|
||||
this.anchorYUnits_ == IconAnchorUnits.FRACTION) {
|
||||
if (!size) {
|
||||
return null;
|
||||
}
|
||||
anchor = this.anchor_.slice();
|
||||
if (this.anchorXUnits_ == IconAnchorUnits.FRACTION) {
|
||||
anchor[0] *= size[0];
|
||||
}
|
||||
if (this.anchorYUnits_ == IconAnchorUnits.FRACTION) {
|
||||
anchor[1] *= size[1];
|
||||
}
|
||||
}
|
||||
|
||||
if (this.anchorOrigin_ != IconOrigin.TOP_LEFT) {
|
||||
if (!size) {
|
||||
return null;
|
||||
}
|
||||
if (anchor === this.anchor_) {
|
||||
anchor = this.anchor_.slice();
|
||||
}
|
||||
if (this.anchorOrigin_ == IconOrigin.TOP_RIGHT ||
|
||||
this.anchorOrigin_ == IconOrigin.BOTTOM_RIGHT) {
|
||||
anchor[0] = -anchor[0] + size[0];
|
||||
}
|
||||
if (this.anchorOrigin_ == IconOrigin.BOTTOM_LEFT ||
|
||||
this.anchorOrigin_ == IconOrigin.BOTTOM_RIGHT) {
|
||||
anchor[1] = -anchor[1] + size[1];
|
||||
}
|
||||
}
|
||||
this.normalizedAnchor_ = anchor;
|
||||
return this.normalizedAnchor_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the anchor point. The anchor determines the center point for the
|
||||
* symbolizer.
|
||||
*
|
||||
* @param {Array.<number>} anchor Anchor.
|
||||
* @api
|
||||
*/
|
||||
Icon.prototype.setAnchor = function(anchor) {
|
||||
this.anchor_ = anchor;
|
||||
this.normalizedAnchor_ = null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the icon color.
|
||||
* @return {module:ol/color~Color} Color.
|
||||
* @api
|
||||
*/
|
||||
Icon.prototype.getColor = function() {
|
||||
return this.color_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the image icon.
|
||||
* @param {number} pixelRatio Pixel ratio.
|
||||
* @return {HTMLImageElement|HTMLCanvasElement} Image or Canvas element.
|
||||
* @override
|
||||
* @api
|
||||
*/
|
||||
Icon.prototype.getImage = function(pixelRatio) {
|
||||
return this.iconImage_.getImage(pixelRatio);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
Icon.prototype.getImageSize = function() {
|
||||
return this.iconImage_.getSize();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
Icon.prototype.getHitDetectionImageSize = function() {
|
||||
return this.getImageSize();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
Icon.prototype.getImageState = function() {
|
||||
return this.iconImage_.getImageState();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
Icon.prototype.getHitDetectionImage = function(pixelRatio) {
|
||||
return this.iconImage_.getHitDetectionImage(pixelRatio);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @api
|
||||
*/
|
||||
Icon.prototype.getOrigin = function() {
|
||||
if (this.origin_) {
|
||||
return this.origin_;
|
||||
}
|
||||
let offset = this.offset_;
|
||||
|
||||
if (this.offsetOrigin_ != IconOrigin.TOP_LEFT) {
|
||||
const size = this.getSize();
|
||||
const iconImageSize = this.iconImage_.getSize();
|
||||
if (!size || !iconImageSize) {
|
||||
return null;
|
||||
}
|
||||
offset = offset.slice();
|
||||
if (this.offsetOrigin_ == IconOrigin.TOP_RIGHT ||
|
||||
this.offsetOrigin_ == IconOrigin.BOTTOM_RIGHT) {
|
||||
offset[0] = iconImageSize[0] - size[0] - offset[0];
|
||||
}
|
||||
if (this.offsetOrigin_ == IconOrigin.BOTTOM_LEFT ||
|
||||
this.offsetOrigin_ == IconOrigin.BOTTOM_RIGHT) {
|
||||
offset[1] = iconImageSize[1] - size[1] - offset[1];
|
||||
}
|
||||
}
|
||||
this.origin_ = offset;
|
||||
return this.origin_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the image URL.
|
||||
* @return {string|undefined} Image src.
|
||||
* @api
|
||||
*/
|
||||
Icon.prototype.getSrc = function() {
|
||||
return this.iconImage_.getSrc();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @api
|
||||
*/
|
||||
Icon.prototype.getSize = function() {
|
||||
return !this.size_ ? this.iconImage_.getSize() : this.size_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
Icon.prototype.listenImageChange = function(listener, thisArg) {
|
||||
return listen(this.iconImage_, EventType.CHANGE,
|
||||
listener, thisArg);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Load not yet loaded URI.
|
||||
* When rendering a feature with an icon style, the vector renderer will
|
||||
* automatically call this method. However, you might want to call this
|
||||
* method yourself for preloading or other purposes.
|
||||
* @override
|
||||
* @api
|
||||
*/
|
||||
Icon.prototype.load = function() {
|
||||
this.iconImage_.load();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
Icon.prototype.unlistenImageChange = function(listener, thisArg) {
|
||||
unlisten(this.iconImage_, EventType.CHANGE,
|
||||
listener, thisArg);
|
||||
};
|
||||
export default Icon;
|
||||
|
||||
@@ -19,74 +19,227 @@ import {shared as iconImageCache} from '../style/IconImageCache.js';
|
||||
* @param {module:ol/color~Color} color Color.
|
||||
* @extends {module:ol/events/EventTarget}
|
||||
*/
|
||||
const IconImage = function(image, src, size, crossOrigin, imageState, color) {
|
||||
class IconImage {
|
||||
constructor(image, src, size, crossOrigin, imageState, color) {
|
||||
|
||||
EventTarget.call(this);
|
||||
EventTarget.call(this);
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {HTMLImageElement|HTMLCanvasElement}
|
||||
*/
|
||||
this.hitDetectionImage_ = null;
|
||||
/**
|
||||
* @private
|
||||
* @type {HTMLImageElement|HTMLCanvasElement}
|
||||
*/
|
||||
this.hitDetectionImage_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {HTMLImageElement|HTMLCanvasElement}
|
||||
*/
|
||||
this.image_ = !image ? new Image() : image;
|
||||
/**
|
||||
* @private
|
||||
* @type {HTMLImageElement|HTMLCanvasElement}
|
||||
*/
|
||||
this.image_ = !image ? new Image() : image;
|
||||
|
||||
if (crossOrigin !== null) {
|
||||
this.image_.crossOrigin = crossOrigin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {HTMLCanvasElement}
|
||||
*/
|
||||
this.canvas_ = color ?
|
||||
/** @type {HTMLCanvasElement} */ (document.createElement('CANVAS')) :
|
||||
null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/color~Color}
|
||||
*/
|
||||
this.color_ = color;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<module:ol/events~EventsKey>}
|
||||
*/
|
||||
this.imageListenerKeys_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/ImageState}
|
||||
*/
|
||||
this.imageState_ = imageState;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/size~Size}
|
||||
*/
|
||||
this.size_ = size;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {string|undefined}
|
||||
*/
|
||||
this.src_ = src;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.tainting_ = false;
|
||||
if (this.imageState_ == ImageState.LOADED) {
|
||||
this.determineTainting_();
|
||||
}
|
||||
|
||||
if (crossOrigin !== null) {
|
||||
this.image_.crossOrigin = crossOrigin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {HTMLCanvasElement}
|
||||
*/
|
||||
this.canvas_ = color ?
|
||||
/** @type {HTMLCanvasElement} */ (document.createElement('CANVAS')) :
|
||||
null;
|
||||
determineTainting_() {
|
||||
const context = createCanvasContext2D(1, 1);
|
||||
try {
|
||||
context.drawImage(this.image_, 0, 0);
|
||||
context.getImageData(0, 0, 1, 1);
|
||||
} catch (e) {
|
||||
this.tainting_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/color~Color}
|
||||
*/
|
||||
this.color_ = color;
|
||||
dispatchChangeEvent_() {
|
||||
this.dispatchEvent(EventType.CHANGE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<module:ol/events~EventsKey>}
|
||||
*/
|
||||
this.imageListenerKeys_ = null;
|
||||
handleImageError_() {
|
||||
this.imageState_ = ImageState.ERROR;
|
||||
this.unlistenImage_();
|
||||
this.dispatchChangeEvent_();
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/ImageState}
|
||||
*/
|
||||
this.imageState_ = imageState;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/size~Size}
|
||||
*/
|
||||
this.size_ = size;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {string|undefined}
|
||||
*/
|
||||
this.src_ = src;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.tainting_ = false;
|
||||
if (this.imageState_ == ImageState.LOADED) {
|
||||
handleImageLoad_() {
|
||||
this.imageState_ = ImageState.LOADED;
|
||||
if (this.size_) {
|
||||
this.image_.width = this.size_[0];
|
||||
this.image_.height = this.size_[1];
|
||||
}
|
||||
this.size_ = [this.image_.width, this.image_.height];
|
||||
this.unlistenImage_();
|
||||
this.determineTainting_();
|
||||
this.replaceColor_();
|
||||
this.dispatchChangeEvent_();
|
||||
}
|
||||
|
||||
};
|
||||
/**
|
||||
* @param {number} pixelRatio Pixel ratio.
|
||||
* @return {HTMLImageElement|HTMLCanvasElement} Image or Canvas element.
|
||||
*/
|
||||
getImage(pixelRatio) {
|
||||
return this.canvas_ ? this.canvas_ : this.image_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {module:ol/ImageState} Image state.
|
||||
*/
|
||||
getImageState() {
|
||||
return this.imageState_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} pixelRatio Pixel ratio.
|
||||
* @return {HTMLImageElement|HTMLCanvasElement} Image element.
|
||||
*/
|
||||
getHitDetectionImage(pixelRatio) {
|
||||
if (!this.hitDetectionImage_) {
|
||||
if (this.tainting_) {
|
||||
const width = this.size_[0];
|
||||
const height = this.size_[1];
|
||||
const context = createCanvasContext2D(width, height);
|
||||
context.fillRect(0, 0, width, height);
|
||||
this.hitDetectionImage_ = context.canvas;
|
||||
} else {
|
||||
this.hitDetectionImage_ = this.image_;
|
||||
}
|
||||
}
|
||||
return this.hitDetectionImage_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {module:ol/size~Size} Image size.
|
||||
*/
|
||||
getSize() {
|
||||
return this.size_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {string|undefined} Image src.
|
||||
*/
|
||||
getSrc() {
|
||||
return this.src_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load not yet loaded URI.
|
||||
*/
|
||||
load() {
|
||||
if (this.imageState_ == ImageState.IDLE) {
|
||||
this.imageState_ = ImageState.LOADING;
|
||||
this.imageListenerKeys_ = [
|
||||
listenOnce(this.image_, EventType.ERROR,
|
||||
this.handleImageError_, this),
|
||||
listenOnce(this.image_, EventType.LOAD,
|
||||
this.handleImageLoad_, this)
|
||||
];
|
||||
try {
|
||||
this.image_.src = this.src_;
|
||||
} catch (e) {
|
||||
this.handleImageError_();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
replaceColor_() {
|
||||
if (this.tainting_ || this.color_ === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.canvas_.width = this.image_.width;
|
||||
this.canvas_.height = this.image_.height;
|
||||
|
||||
const ctx = this.canvas_.getContext('2d');
|
||||
ctx.drawImage(this.image_, 0, 0);
|
||||
|
||||
const imgData = ctx.getImageData(0, 0, this.image_.width, this.image_.height);
|
||||
const data = imgData.data;
|
||||
const r = this.color_[0] / 255.0;
|
||||
const g = this.color_[1] / 255.0;
|
||||
const b = this.color_[2] / 255.0;
|
||||
|
||||
for (let i = 0, ii = data.length; i < ii; i += 4) {
|
||||
data[i] *= r;
|
||||
data[i + 1] *= g;
|
||||
data[i + 2] *= b;
|
||||
}
|
||||
ctx.putImageData(imgData, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Discards event handlers which listen for load completion or errors.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
unlistenImage_() {
|
||||
this.imageListenerKeys_.forEach(unlistenByKey);
|
||||
this.imageListenerKeys_ = null;
|
||||
}
|
||||
}
|
||||
|
||||
inherits(IconImage, EventTarget);
|
||||
|
||||
@@ -110,165 +263,4 @@ export function get(image, src, size, crossOrigin, imageState, color) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
IconImage.prototype.determineTainting_ = function() {
|
||||
const context = createCanvasContext2D(1, 1);
|
||||
try {
|
||||
context.drawImage(this.image_, 0, 0);
|
||||
context.getImageData(0, 0, 1, 1);
|
||||
} catch (e) {
|
||||
this.tainting_ = true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
IconImage.prototype.dispatchChangeEvent_ = function() {
|
||||
this.dispatchEvent(EventType.CHANGE);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
IconImage.prototype.handleImageError_ = function() {
|
||||
this.imageState_ = ImageState.ERROR;
|
||||
this.unlistenImage_();
|
||||
this.dispatchChangeEvent_();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
IconImage.prototype.handleImageLoad_ = function() {
|
||||
this.imageState_ = ImageState.LOADED;
|
||||
if (this.size_) {
|
||||
this.image_.width = this.size_[0];
|
||||
this.image_.height = this.size_[1];
|
||||
}
|
||||
this.size_ = [this.image_.width, this.image_.height];
|
||||
this.unlistenImage_();
|
||||
this.determineTainting_();
|
||||
this.replaceColor_();
|
||||
this.dispatchChangeEvent_();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} pixelRatio Pixel ratio.
|
||||
* @return {HTMLImageElement|HTMLCanvasElement} Image or Canvas element.
|
||||
*/
|
||||
IconImage.prototype.getImage = function(pixelRatio) {
|
||||
return this.canvas_ ? this.canvas_ : this.image_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {module:ol/ImageState} Image state.
|
||||
*/
|
||||
IconImage.prototype.getImageState = function() {
|
||||
return this.imageState_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} pixelRatio Pixel ratio.
|
||||
* @return {HTMLImageElement|HTMLCanvasElement} Image element.
|
||||
*/
|
||||
IconImage.prototype.getHitDetectionImage = function(pixelRatio) {
|
||||
if (!this.hitDetectionImage_) {
|
||||
if (this.tainting_) {
|
||||
const width = this.size_[0];
|
||||
const height = this.size_[1];
|
||||
const context = createCanvasContext2D(width, height);
|
||||
context.fillRect(0, 0, width, height);
|
||||
this.hitDetectionImage_ = context.canvas;
|
||||
} else {
|
||||
this.hitDetectionImage_ = this.image_;
|
||||
}
|
||||
}
|
||||
return this.hitDetectionImage_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {module:ol/size~Size} Image size.
|
||||
*/
|
||||
IconImage.prototype.getSize = function() {
|
||||
return this.size_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {string|undefined} Image src.
|
||||
*/
|
||||
IconImage.prototype.getSrc = function() {
|
||||
return this.src_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Load not yet loaded URI.
|
||||
*/
|
||||
IconImage.prototype.load = function() {
|
||||
if (this.imageState_ == ImageState.IDLE) {
|
||||
this.imageState_ = ImageState.LOADING;
|
||||
this.imageListenerKeys_ = [
|
||||
listenOnce(this.image_, EventType.ERROR,
|
||||
this.handleImageError_, this),
|
||||
listenOnce(this.image_, EventType.LOAD,
|
||||
this.handleImageLoad_, this)
|
||||
];
|
||||
try {
|
||||
this.image_.src = this.src_;
|
||||
} catch (e) {
|
||||
this.handleImageError_();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
IconImage.prototype.replaceColor_ = function() {
|
||||
if (this.tainting_ || this.color_ === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.canvas_.width = this.image_.width;
|
||||
this.canvas_.height = this.image_.height;
|
||||
|
||||
const ctx = this.canvas_.getContext('2d');
|
||||
ctx.drawImage(this.image_, 0, 0);
|
||||
|
||||
const imgData = ctx.getImageData(0, 0, this.image_.width, this.image_.height);
|
||||
const data = imgData.data;
|
||||
const r = this.color_[0] / 255.0;
|
||||
const g = this.color_[1] / 255.0;
|
||||
const b = this.color_[2] / 255.0;
|
||||
|
||||
for (let i = 0, ii = data.length; i < ii; i += 4) {
|
||||
data[i] *= r;
|
||||
data[i + 1] *= g;
|
||||
data[i + 2] *= b;
|
||||
}
|
||||
ctx.putImageData(imgData, 0, 0);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Discards event handlers which listen for load completion or errors.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
IconImage.prototype.unlistenImage_ = function() {
|
||||
this.imageListenerKeys_.forEach(unlistenByKey);
|
||||
this.imageListenerKeys_ = null;
|
||||
};
|
||||
export default IconImage;
|
||||
|
||||
@@ -7,26 +7,87 @@ import {asString} from '../color.js';
|
||||
* Singleton class. Available through {@link module:ol/style/IconImageCache~shared}.
|
||||
* @constructor
|
||||
*/
|
||||
const IconImageCache = function() {
|
||||
class IconImageCache {
|
||||
constructor() {
|
||||
|
||||
/**
|
||||
* @type {!Object.<string, module:ol/style/IconImage>}
|
||||
* @private
|
||||
*/
|
||||
this.cache_ = {};
|
||||
/**
|
||||
* @type {!Object.<string, module:ol/style/IconImage>}
|
||||
* @private
|
||||
*/
|
||||
this.cache_ = {};
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.cacheSize_ = 0;
|
||||
/**
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.cacheSize_ = 0;
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.maxCacheSize_ = 32;
|
||||
};
|
||||
/**
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.maxCacheSize_ = 32;
|
||||
}
|
||||
|
||||
/**
|
||||
* FIXME empty description for jsdoc
|
||||
*/
|
||||
clear() {
|
||||
this.cache_ = {};
|
||||
this.cacheSize_ = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* FIXME empty description for jsdoc
|
||||
*/
|
||||
expire() {
|
||||
if (this.cacheSize_ > this.maxCacheSize_) {
|
||||
let i = 0;
|
||||
for (const key in this.cache_) {
|
||||
const iconImage = this.cache_[key];
|
||||
if ((i++ & 3) === 0 && !iconImage.hasListener()) {
|
||||
delete this.cache_[key];
|
||||
--this.cacheSize_;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} src Src.
|
||||
* @param {?string} crossOrigin Cross origin.
|
||||
* @param {module:ol/color~Color} color Color.
|
||||
* @return {module:ol/style/IconImage} Icon image.
|
||||
*/
|
||||
get(src, crossOrigin, color) {
|
||||
const key = getKey(src, crossOrigin, color);
|
||||
return key in this.cache_ ? this.cache_[key] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} src Src.
|
||||
* @param {?string} crossOrigin Cross origin.
|
||||
* @param {module:ol/color~Color} color Color.
|
||||
* @param {module:ol/style/IconImage} iconImage Icon image.
|
||||
*/
|
||||
set(src, crossOrigin, color, iconImage) {
|
||||
const key = getKey(src, crossOrigin, color);
|
||||
this.cache_[key] = iconImage;
|
||||
++this.cacheSize_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the cache size of the icon cache. Default is `32`. Change this value when
|
||||
* your map uses more than 32 different icon images and you are not caching icon
|
||||
* styles on the application level.
|
||||
* @param {number} maxCacheSize Cache max size.
|
||||
* @api
|
||||
*/
|
||||
setSize(maxCacheSize) {
|
||||
this.maxCacheSize_ = maxCacheSize;
|
||||
this.expire();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@@ -41,68 +102,6 @@ function getKey(src, crossOrigin, color) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* FIXME empty description for jsdoc
|
||||
*/
|
||||
IconImageCache.prototype.clear = function() {
|
||||
this.cache_ = {};
|
||||
this.cacheSize_ = 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* FIXME empty description for jsdoc
|
||||
*/
|
||||
IconImageCache.prototype.expire = function() {
|
||||
if (this.cacheSize_ > this.maxCacheSize_) {
|
||||
let i = 0;
|
||||
for (const key in this.cache_) {
|
||||
const iconImage = this.cache_[key];
|
||||
if ((i++ & 3) === 0 && !iconImage.hasListener()) {
|
||||
delete this.cache_[key];
|
||||
--this.cacheSize_;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} src Src.
|
||||
* @param {?string} crossOrigin Cross origin.
|
||||
* @param {module:ol/color~Color} color Color.
|
||||
* @return {module:ol/style/IconImage} Icon image.
|
||||
*/
|
||||
IconImageCache.prototype.get = function(src, crossOrigin, color) {
|
||||
const key = getKey(src, crossOrigin, color);
|
||||
return key in this.cache_ ? this.cache_[key] : null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} src Src.
|
||||
* @param {?string} crossOrigin Cross origin.
|
||||
* @param {module:ol/color~Color} color Color.
|
||||
* @param {module:ol/style/IconImage} iconImage Icon image.
|
||||
*/
|
||||
IconImageCache.prototype.set = function(src, crossOrigin, color, iconImage) {
|
||||
const key = getKey(src, crossOrigin, color);
|
||||
this.cache_[key] = iconImage;
|
||||
++this.cacheSize_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the cache size of the icon cache. Default is `32`. Change this value when
|
||||
* your map uses more than 32 different icon images and you are not caching icon
|
||||
* styles on the application level.
|
||||
* @param {number} maxCacheSize Cache max size.
|
||||
* @api
|
||||
*/
|
||||
IconImageCache.prototype.setSize = function(maxCacheSize) {
|
||||
this.maxCacheSize_ = maxCacheSize;
|
||||
this.expire();
|
||||
};
|
||||
export default IconImageCache;
|
||||
|
||||
|
||||
|
||||
@@ -24,231 +24,213 @@
|
||||
* @param {module:ol/style/Image~Options} options Options.
|
||||
* @api
|
||||
*/
|
||||
const ImageStyle = function(options) {
|
||||
class ImageStyle {
|
||||
constructor(options) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.opacity_ = options.opacity;
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.opacity_ = options.opacity;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.rotateWithView_ = options.rotateWithView;
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.rotateWithView_ = options.rotateWithView;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.rotation_ = options.rotation;
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.rotation_ = options.rotation;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.scale_ = options.scale;
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.scale_ = options.scale;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.snapToPixel_ = options.snapToPixel;
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.snapToPixel_ = options.snapToPixel;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the symbolizer opacity.
|
||||
* @return {number} Opacity.
|
||||
* @api
|
||||
*/
|
||||
getOpacity() {
|
||||
return this.opacity_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the symbolizer opacity.
|
||||
* @return {number} Opacity.
|
||||
* @api
|
||||
*/
|
||||
ImageStyle.prototype.getOpacity = function() {
|
||||
return this.opacity_;
|
||||
};
|
||||
/**
|
||||
* Determine whether the symbolizer rotates with the map.
|
||||
* @return {boolean} Rotate with map.
|
||||
* @api
|
||||
*/
|
||||
getRotateWithView() {
|
||||
return this.rotateWithView_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the symoblizer rotation.
|
||||
* @return {number} Rotation.
|
||||
* @api
|
||||
*/
|
||||
getRotation() {
|
||||
return this.rotation_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the symbolizer rotates with the map.
|
||||
* @return {boolean} Rotate with map.
|
||||
* @api
|
||||
*/
|
||||
ImageStyle.prototype.getRotateWithView = function() {
|
||||
return this.rotateWithView_;
|
||||
};
|
||||
/**
|
||||
* Get the symbolizer scale.
|
||||
* @return {number} Scale.
|
||||
* @api
|
||||
*/
|
||||
getScale() {
|
||||
return this.scale_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the symbolizer should be snapped to a pixel.
|
||||
* @return {boolean} The symbolizer should snap to a pixel.
|
||||
* @api
|
||||
*/
|
||||
getSnapToPixel() {
|
||||
return this.snapToPixel_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the symoblizer rotation.
|
||||
* @return {number} Rotation.
|
||||
* @api
|
||||
*/
|
||||
ImageStyle.prototype.getRotation = function() {
|
||||
return this.rotation_;
|
||||
};
|
||||
/**
|
||||
* Get the anchor point in pixels. The anchor determines the center point for the
|
||||
* symbolizer.
|
||||
* @abstract
|
||||
* @return {Array.<number>} Anchor.
|
||||
*/
|
||||
getAnchor() {}
|
||||
|
||||
/**
|
||||
* Get the image element for the symbolizer.
|
||||
* @abstract
|
||||
* @param {number} pixelRatio Pixel ratio.
|
||||
* @return {HTMLCanvasElement|HTMLVideoElement|HTMLImageElement} Image element.
|
||||
*/
|
||||
getImage(pixelRatio) {}
|
||||
|
||||
/**
|
||||
* Get the symbolizer scale.
|
||||
* @return {number} Scale.
|
||||
* @api
|
||||
*/
|
||||
ImageStyle.prototype.getScale = function() {
|
||||
return this.scale_;
|
||||
};
|
||||
/**
|
||||
* @abstract
|
||||
* @param {number} pixelRatio Pixel ratio.
|
||||
* @return {HTMLCanvasElement|HTMLVideoElement|HTMLImageElement} Image element.
|
||||
*/
|
||||
getHitDetectionImage(pixelRatio) {}
|
||||
|
||||
/**
|
||||
* @abstract
|
||||
* @return {module:ol/ImageState} Image state.
|
||||
*/
|
||||
getImageState() {}
|
||||
|
||||
/**
|
||||
* Determine whether the symbolizer should be snapped to a pixel.
|
||||
* @return {boolean} The symbolizer should snap to a pixel.
|
||||
* @api
|
||||
*/
|
||||
ImageStyle.prototype.getSnapToPixel = function() {
|
||||
return this.snapToPixel_;
|
||||
};
|
||||
/**
|
||||
* @abstract
|
||||
* @return {module:ol/size~Size} Image size.
|
||||
*/
|
||||
getImageSize() {}
|
||||
|
||||
/**
|
||||
* @abstract
|
||||
* @return {module:ol/size~Size} Size of the hit-detection image.
|
||||
*/
|
||||
getHitDetectionImageSize() {}
|
||||
|
||||
/**
|
||||
* Get the anchor point in pixels. The anchor determines the center point for the
|
||||
* symbolizer.
|
||||
* @abstract
|
||||
* @return {Array.<number>} Anchor.
|
||||
*/
|
||||
ImageStyle.prototype.getAnchor = function() {};
|
||||
/**
|
||||
* Get the origin of the symbolizer.
|
||||
* @abstract
|
||||
* @return {Array.<number>} Origin.
|
||||
*/
|
||||
getOrigin() {}
|
||||
|
||||
/**
|
||||
* Get the size of the symbolizer (in pixels).
|
||||
* @abstract
|
||||
* @return {module:ol/size~Size} Size.
|
||||
*/
|
||||
getSize() {}
|
||||
|
||||
/**
|
||||
* Get the image element for the symbolizer.
|
||||
* @abstract
|
||||
* @param {number} pixelRatio Pixel ratio.
|
||||
* @return {HTMLCanvasElement|HTMLVideoElement|HTMLImageElement} Image element.
|
||||
*/
|
||||
ImageStyle.prototype.getImage = function(pixelRatio) {};
|
||||
/**
|
||||
* Set the opacity.
|
||||
*
|
||||
* @param {number} opacity Opacity.
|
||||
* @api
|
||||
*/
|
||||
setOpacity(opacity) {
|
||||
this.opacity_ = opacity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether to rotate the style with the view.
|
||||
*
|
||||
* @param {boolean} rotateWithView Rotate with map.
|
||||
* @api
|
||||
*/
|
||||
setRotateWithView(rotateWithView) {
|
||||
this.rotateWithView_ = rotateWithView;
|
||||
}
|
||||
|
||||
/**
|
||||
* @abstract
|
||||
* @param {number} pixelRatio Pixel ratio.
|
||||
* @return {HTMLCanvasElement|HTMLVideoElement|HTMLImageElement} Image element.
|
||||
*/
|
||||
ImageStyle.prototype.getHitDetectionImage = function(pixelRatio) {};
|
||||
/**
|
||||
* Set the rotation.
|
||||
*
|
||||
* @param {number} rotation Rotation.
|
||||
* @api
|
||||
*/
|
||||
setRotation(rotation) {
|
||||
this.rotation_ = rotation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the scale.
|
||||
*
|
||||
* @param {number} scale Scale.
|
||||
* @api
|
||||
*/
|
||||
setScale(scale) {
|
||||
this.scale_ = scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* @abstract
|
||||
* @return {module:ol/ImageState} Image state.
|
||||
*/
|
||||
ImageStyle.prototype.getImageState = function() {};
|
||||
/**
|
||||
* Set whether to snap the image to the closest pixel.
|
||||
*
|
||||
* @param {boolean} snapToPixel Snap to pixel?
|
||||
* @api
|
||||
*/
|
||||
setSnapToPixel(snapToPixel) {
|
||||
this.snapToPixel_ = snapToPixel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @abstract
|
||||
* @param {function(this: T, module:ol/events/Event)} listener Listener function.
|
||||
* @param {T} thisArg Value to use as `this` when executing `listener`.
|
||||
* @return {module:ol/events~EventsKey|undefined} Listener key.
|
||||
* @template T
|
||||
*/
|
||||
listenImageChange(listener, thisArg) {}
|
||||
|
||||
/**
|
||||
* @abstract
|
||||
* @return {module:ol/size~Size} Image size.
|
||||
*/
|
||||
ImageStyle.prototype.getImageSize = function() {};
|
||||
/**
|
||||
* Load not yet loaded URI.
|
||||
* @abstract
|
||||
*/
|
||||
load() {}
|
||||
|
||||
/**
|
||||
* @abstract
|
||||
* @param {function(this: T, module:ol/events/Event)} listener Listener function.
|
||||
* @param {T} thisArg Value to use as `this` when executing `listener`.
|
||||
* @template T
|
||||
*/
|
||||
unlistenImageChange(listener, thisArg) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* @abstract
|
||||
* @return {module:ol/size~Size} Size of the hit-detection image.
|
||||
*/
|
||||
ImageStyle.prototype.getHitDetectionImageSize = function() {};
|
||||
|
||||
|
||||
/**
|
||||
* Get the origin of the symbolizer.
|
||||
* @abstract
|
||||
* @return {Array.<number>} Origin.
|
||||
*/
|
||||
ImageStyle.prototype.getOrigin = function() {};
|
||||
|
||||
|
||||
/**
|
||||
* Get the size of the symbolizer (in pixels).
|
||||
* @abstract
|
||||
* @return {module:ol/size~Size} Size.
|
||||
*/
|
||||
ImageStyle.prototype.getSize = function() {};
|
||||
|
||||
|
||||
/**
|
||||
* Set the opacity.
|
||||
*
|
||||
* @param {number} opacity Opacity.
|
||||
* @api
|
||||
*/
|
||||
ImageStyle.prototype.setOpacity = function(opacity) {
|
||||
this.opacity_ = opacity;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set whether to rotate the style with the view.
|
||||
*
|
||||
* @param {boolean} rotateWithView Rotate with map.
|
||||
* @api
|
||||
*/
|
||||
ImageStyle.prototype.setRotateWithView = function(rotateWithView) {
|
||||
this.rotateWithView_ = rotateWithView;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the rotation.
|
||||
*
|
||||
* @param {number} rotation Rotation.
|
||||
* @api
|
||||
*/
|
||||
ImageStyle.prototype.setRotation = function(rotation) {
|
||||
this.rotation_ = rotation;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the scale.
|
||||
*
|
||||
* @param {number} scale Scale.
|
||||
* @api
|
||||
*/
|
||||
ImageStyle.prototype.setScale = function(scale) {
|
||||
this.scale_ = scale;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set whether to snap the image to the closest pixel.
|
||||
*
|
||||
* @param {boolean} snapToPixel Snap to pixel?
|
||||
* @api
|
||||
*/
|
||||
ImageStyle.prototype.setSnapToPixel = function(snapToPixel) {
|
||||
this.snapToPixel_ = snapToPixel;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @abstract
|
||||
* @param {function(this: T, module:ol/events/Event)} listener Listener function.
|
||||
* @param {T} thisArg Value to use as `this` when executing `listener`.
|
||||
* @return {module:ol/events~EventsKey|undefined} Listener key.
|
||||
* @template T
|
||||
*/
|
||||
ImageStyle.prototype.listenImageChange = function(listener, thisArg) {};
|
||||
|
||||
|
||||
/**
|
||||
* Load not yet loaded URI.
|
||||
* @abstract
|
||||
*/
|
||||
ImageStyle.prototype.load = function() {};
|
||||
|
||||
|
||||
/**
|
||||
* @abstract
|
||||
* @param {function(this: T, module:ol/events/Event)} listener Listener function.
|
||||
* @param {T} thisArg Value to use as `this` when executing `listener`.
|
||||
* @template T
|
||||
*/
|
||||
ImageStyle.prototype.unlistenImageChange = function(listener, thisArg) {};
|
||||
export default ImageStyle;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -31,269 +31,256 @@ import {getUid} from '../util.js';
|
||||
* @param {module:ol/style/Stroke~Options=} opt_options Options.
|
||||
* @api
|
||||
*/
|
||||
const Stroke = function(opt_options) {
|
||||
class Stroke {
|
||||
constructor(opt_options) {
|
||||
|
||||
const options = opt_options || {};
|
||||
const options = opt_options || {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/color~Color|module:ol/colorlike~ColorLike}
|
||||
*/
|
||||
this.color_ = options.color !== undefined ? options.color : null;
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/color~Color|module:ol/colorlike~ColorLike}
|
||||
*/
|
||||
this.color_ = options.color !== undefined ? options.color : null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {string|undefined}
|
||||
*/
|
||||
this.lineCap_ = options.lineCap;
|
||||
/**
|
||||
* @private
|
||||
* @type {string|undefined}
|
||||
*/
|
||||
this.lineCap_ = options.lineCap;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<number>}
|
||||
*/
|
||||
this.lineDash_ = options.lineDash !== undefined ? options.lineDash : null;
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<number>}
|
||||
*/
|
||||
this.lineDash_ = options.lineDash !== undefined ? options.lineDash : null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number|undefined}
|
||||
*/
|
||||
this.lineDashOffset_ = options.lineDashOffset;
|
||||
/**
|
||||
* @private
|
||||
* @type {number|undefined}
|
||||
*/
|
||||
this.lineDashOffset_ = options.lineDashOffset;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {string|undefined}
|
||||
*/
|
||||
this.lineJoin_ = options.lineJoin;
|
||||
/**
|
||||
* @private
|
||||
* @type {string|undefined}
|
||||
*/
|
||||
this.lineJoin_ = options.lineJoin;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number|undefined}
|
||||
*/
|
||||
this.miterLimit_ = options.miterLimit;
|
||||
/**
|
||||
* @private
|
||||
* @type {number|undefined}
|
||||
*/
|
||||
this.miterLimit_ = options.miterLimit;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number|undefined}
|
||||
*/
|
||||
this.width_ = options.width;
|
||||
/**
|
||||
* @private
|
||||
* @type {number|undefined}
|
||||
*/
|
||||
this.width_ = options.width;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {string|undefined}
|
||||
*/
|
||||
this.checksum_ = undefined;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Clones the style.
|
||||
* @return {module:ol/style/Stroke} The cloned style.
|
||||
* @api
|
||||
*/
|
||||
Stroke.prototype.clone = function() {
|
||||
const color = this.getColor();
|
||||
return new Stroke({
|
||||
color: (color && color.slice) ? color.slice() : color || undefined,
|
||||
lineCap: this.getLineCap(),
|
||||
lineDash: this.getLineDash() ? this.getLineDash().slice() : undefined,
|
||||
lineDashOffset: this.getLineDashOffset(),
|
||||
lineJoin: this.getLineJoin(),
|
||||
miterLimit: this.getMiterLimit(),
|
||||
width: this.getWidth()
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the stroke color.
|
||||
* @return {module:ol/color~Color|module:ol/colorlike~ColorLike} Color.
|
||||
* @api
|
||||
*/
|
||||
Stroke.prototype.getColor = function() {
|
||||
return this.color_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the line cap type for the stroke.
|
||||
* @return {string|undefined} Line cap.
|
||||
* @api
|
||||
*/
|
||||
Stroke.prototype.getLineCap = function() {
|
||||
return this.lineCap_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the line dash style for the stroke.
|
||||
* @return {Array.<number>} Line dash.
|
||||
* @api
|
||||
*/
|
||||
Stroke.prototype.getLineDash = function() {
|
||||
return this.lineDash_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the line dash offset for the stroke.
|
||||
* @return {number|undefined} Line dash offset.
|
||||
* @api
|
||||
*/
|
||||
Stroke.prototype.getLineDashOffset = function() {
|
||||
return this.lineDashOffset_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the line join type for the stroke.
|
||||
* @return {string|undefined} Line join.
|
||||
* @api
|
||||
*/
|
||||
Stroke.prototype.getLineJoin = function() {
|
||||
return this.lineJoin_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the miter limit for the stroke.
|
||||
* @return {number|undefined} Miter limit.
|
||||
* @api
|
||||
*/
|
||||
Stroke.prototype.getMiterLimit = function() {
|
||||
return this.miterLimit_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the stroke width.
|
||||
* @return {number|undefined} Width.
|
||||
* @api
|
||||
*/
|
||||
Stroke.prototype.getWidth = function() {
|
||||
return this.width_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the color.
|
||||
*
|
||||
* @param {module:ol/color~Color|module:ol/colorlike~ColorLike} color Color.
|
||||
* @api
|
||||
*/
|
||||
Stroke.prototype.setColor = function(color) {
|
||||
this.color_ = color;
|
||||
this.checksum_ = undefined;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the line cap.
|
||||
*
|
||||
* @param {string|undefined} lineCap Line cap.
|
||||
* @api
|
||||
*/
|
||||
Stroke.prototype.setLineCap = function(lineCap) {
|
||||
this.lineCap_ = lineCap;
|
||||
this.checksum_ = undefined;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the line dash.
|
||||
*
|
||||
* Please note that Internet Explorer 10 and lower [do not support][mdn] the
|
||||
* `setLineDash` method on the `CanvasRenderingContext2D` and therefore this
|
||||
* property will have no visual effect in these browsers.
|
||||
*
|
||||
* [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash#Browser_compatibility
|
||||
*
|
||||
* @param {Array.<number>} lineDash Line dash.
|
||||
* @api
|
||||
*/
|
||||
Stroke.prototype.setLineDash = function(lineDash) {
|
||||
this.lineDash_ = lineDash;
|
||||
this.checksum_ = undefined;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the line dash offset.
|
||||
*
|
||||
* @param {number|undefined} lineDashOffset Line dash offset.
|
||||
* @api
|
||||
*/
|
||||
Stroke.prototype.setLineDashOffset = function(lineDashOffset) {
|
||||
this.lineDashOffset_ = lineDashOffset;
|
||||
this.checksum_ = undefined;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the line join.
|
||||
*
|
||||
* @param {string|undefined} lineJoin Line join.
|
||||
* @api
|
||||
*/
|
||||
Stroke.prototype.setLineJoin = function(lineJoin) {
|
||||
this.lineJoin_ = lineJoin;
|
||||
this.checksum_ = undefined;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the miter limit.
|
||||
*
|
||||
* @param {number|undefined} miterLimit Miter limit.
|
||||
* @api
|
||||
*/
|
||||
Stroke.prototype.setMiterLimit = function(miterLimit) {
|
||||
this.miterLimit_ = miterLimit;
|
||||
this.checksum_ = undefined;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the width.
|
||||
*
|
||||
* @param {number|undefined} width Width.
|
||||
* @api
|
||||
*/
|
||||
Stroke.prototype.setWidth = function(width) {
|
||||
this.width_ = width;
|
||||
this.checksum_ = undefined;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {string} The checksum.
|
||||
*/
|
||||
Stroke.prototype.getChecksum = function() {
|
||||
if (this.checksum_ === undefined) {
|
||||
this.checksum_ = 's';
|
||||
if (this.color_) {
|
||||
if (typeof this.color_ === 'string') {
|
||||
this.checksum_ += this.color_;
|
||||
} else {
|
||||
this.checksum_ += getUid(this.color_).toString();
|
||||
}
|
||||
} else {
|
||||
this.checksum_ += '-';
|
||||
}
|
||||
this.checksum_ += ',' +
|
||||
(this.lineCap_ !== undefined ?
|
||||
this.lineCap_.toString() : '-') + ',' +
|
||||
(this.lineDash_ ?
|
||||
this.lineDash_.toString() : '-') + ',' +
|
||||
(this.lineDashOffset_ !== undefined ?
|
||||
this.lineDashOffset_ : '-') + ',' +
|
||||
(this.lineJoin_ !== undefined ?
|
||||
this.lineJoin_ : '-') + ',' +
|
||||
(this.miterLimit_ !== undefined ?
|
||||
this.miterLimit_.toString() : '-') + ',' +
|
||||
(this.width_ !== undefined ?
|
||||
this.width_.toString() : '-');
|
||||
/**
|
||||
* @private
|
||||
* @type {string|undefined}
|
||||
*/
|
||||
this.checksum_ = undefined;
|
||||
}
|
||||
|
||||
return this.checksum_;
|
||||
};
|
||||
/**
|
||||
* Clones the style.
|
||||
* @return {module:ol/style/Stroke} The cloned style.
|
||||
* @api
|
||||
*/
|
||||
clone() {
|
||||
const color = this.getColor();
|
||||
return new Stroke({
|
||||
color: (color && color.slice) ? color.slice() : color || undefined,
|
||||
lineCap: this.getLineCap(),
|
||||
lineDash: this.getLineDash() ? this.getLineDash().slice() : undefined,
|
||||
lineDashOffset: this.getLineDashOffset(),
|
||||
lineJoin: this.getLineJoin(),
|
||||
miterLimit: this.getMiterLimit(),
|
||||
width: this.getWidth()
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the stroke color.
|
||||
* @return {module:ol/color~Color|module:ol/colorlike~ColorLike} Color.
|
||||
* @api
|
||||
*/
|
||||
getColor() {
|
||||
return this.color_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the line cap type for the stroke.
|
||||
* @return {string|undefined} Line cap.
|
||||
* @api
|
||||
*/
|
||||
getLineCap() {
|
||||
return this.lineCap_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the line dash style for the stroke.
|
||||
* @return {Array.<number>} Line dash.
|
||||
* @api
|
||||
*/
|
||||
getLineDash() {
|
||||
return this.lineDash_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the line dash offset for the stroke.
|
||||
* @return {number|undefined} Line dash offset.
|
||||
* @api
|
||||
*/
|
||||
getLineDashOffset() {
|
||||
return this.lineDashOffset_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the line join type for the stroke.
|
||||
* @return {string|undefined} Line join.
|
||||
* @api
|
||||
*/
|
||||
getLineJoin() {
|
||||
return this.lineJoin_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the miter limit for the stroke.
|
||||
* @return {number|undefined} Miter limit.
|
||||
* @api
|
||||
*/
|
||||
getMiterLimit() {
|
||||
return this.miterLimit_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the stroke width.
|
||||
* @return {number|undefined} Width.
|
||||
* @api
|
||||
*/
|
||||
getWidth() {
|
||||
return this.width_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the color.
|
||||
*
|
||||
* @param {module:ol/color~Color|module:ol/colorlike~ColorLike} color Color.
|
||||
* @api
|
||||
*/
|
||||
setColor(color) {
|
||||
this.color_ = color;
|
||||
this.checksum_ = undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the line cap.
|
||||
*
|
||||
* @param {string|undefined} lineCap Line cap.
|
||||
* @api
|
||||
*/
|
||||
setLineCap(lineCap) {
|
||||
this.lineCap_ = lineCap;
|
||||
this.checksum_ = undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the line dash.
|
||||
*
|
||||
* Please note that Internet Explorer 10 and lower [do not support][mdn] the
|
||||
* `setLineDash` method on the `CanvasRenderingContext2D` and therefore this
|
||||
* property will have no visual effect in these browsers.
|
||||
*
|
||||
* [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash#Browser_compatibility
|
||||
*
|
||||
* @param {Array.<number>} lineDash Line dash.
|
||||
* @api
|
||||
*/
|
||||
setLineDash(lineDash) {
|
||||
this.lineDash_ = lineDash;
|
||||
this.checksum_ = undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the line dash offset.
|
||||
*
|
||||
* @param {number|undefined} lineDashOffset Line dash offset.
|
||||
* @api
|
||||
*/
|
||||
setLineDashOffset(lineDashOffset) {
|
||||
this.lineDashOffset_ = lineDashOffset;
|
||||
this.checksum_ = undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the line join.
|
||||
*
|
||||
* @param {string|undefined} lineJoin Line join.
|
||||
* @api
|
||||
*/
|
||||
setLineJoin(lineJoin) {
|
||||
this.lineJoin_ = lineJoin;
|
||||
this.checksum_ = undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the miter limit.
|
||||
*
|
||||
* @param {number|undefined} miterLimit Miter limit.
|
||||
* @api
|
||||
*/
|
||||
setMiterLimit(miterLimit) {
|
||||
this.miterLimit_ = miterLimit;
|
||||
this.checksum_ = undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the width.
|
||||
*
|
||||
* @param {number|undefined} width Width.
|
||||
* @api
|
||||
*/
|
||||
setWidth(width) {
|
||||
this.width_ = width;
|
||||
this.checksum_ = undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {string} The checksum.
|
||||
*/
|
||||
getChecksum() {
|
||||
if (this.checksum_ === undefined) {
|
||||
this.checksum_ = 's';
|
||||
if (this.color_) {
|
||||
if (typeof this.color_ === 'string') {
|
||||
this.checksum_ += this.color_;
|
||||
} else {
|
||||
this.checksum_ += getUid(this.color_).toString();
|
||||
}
|
||||
} else {
|
||||
this.checksum_ += '-';
|
||||
}
|
||||
this.checksum_ += ',' +
|
||||
(this.lineCap_ !== undefined ?
|
||||
this.lineCap_.toString() : '-') + ',' +
|
||||
(this.lineDash_ ?
|
||||
this.lineDash_.toString() : '-') + ',' +
|
||||
(this.lineDashOffset_ !== undefined ?
|
||||
this.lineDashOffset_ : '-') + ',' +
|
||||
(this.lineJoin_ !== undefined ?
|
||||
this.lineJoin_ : '-') + ',' +
|
||||
(this.miterLimit_ !== undefined ?
|
||||
this.miterLimit_.toString() : '-') + ',' +
|
||||
(this.width_ !== undefined ?
|
||||
this.width_.toString() : '-');
|
||||
}
|
||||
|
||||
return this.checksum_;
|
||||
}
|
||||
}
|
||||
|
||||
export default Stroke;
|
||||
|
||||
@@ -149,260 +149,246 @@ import Stroke from '../style/Stroke.js';
|
||||
* @param {module:ol/style/Style~Options=} opt_options Style options.
|
||||
* @api
|
||||
*/
|
||||
const Style = function(opt_options) {
|
||||
class Style {
|
||||
constructor(opt_options) {
|
||||
|
||||
const options = opt_options || {};
|
||||
const options = opt_options || {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {string|module:ol/geom/Geometry|module:ol/style/Style~GeometryFunction}
|
||||
*/
|
||||
this.geometry_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {!module:ol/style/Style~GeometryFunction}
|
||||
*/
|
||||
this.geometryFunction_ = defaultGeometryFunction;
|
||||
|
||||
if (options.geometry !== undefined) {
|
||||
this.setGeometry(options.geometry);
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/style/Fill}
|
||||
*/
|
||||
this.fill_ = options.fill !== undefined ? options.fill : null;
|
||||
|
||||
/**
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/style/Image}
|
||||
* @type {string|module:ol/geom/Geometry|module:ol/style/Style~GeometryFunction}
|
||||
*/
|
||||
this.image_ = options.image !== undefined ? options.image : null;
|
||||
this.geometry_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/style/Style~RenderFunction|null}
|
||||
*/
|
||||
this.renderer_ = options.renderer !== undefined ? options.renderer : null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/style/Stroke}
|
||||
*/
|
||||
this.stroke_ = options.stroke !== undefined ? options.stroke : null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/style/Text}
|
||||
*/
|
||||
this.text_ = options.text !== undefined ? options.text : null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number|undefined}
|
||||
*/
|
||||
this.zIndex_ = options.zIndex;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Clones the style.
|
||||
* @return {module:ol/style/Style} The cloned style.
|
||||
* @api
|
||||
*/
|
||||
Style.prototype.clone = function() {
|
||||
let geometry = this.getGeometry();
|
||||
if (geometry && geometry.clone) {
|
||||
geometry = geometry.clone();
|
||||
}
|
||||
return new Style({
|
||||
geometry: geometry,
|
||||
fill: this.getFill() ? this.getFill().clone() : undefined,
|
||||
image: this.getImage() ? this.getImage().clone() : undefined,
|
||||
stroke: this.getStroke() ? this.getStroke().clone() : undefined,
|
||||
text: this.getText() ? this.getText().clone() : undefined,
|
||||
zIndex: this.getZIndex()
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the custom renderer function that was configured with
|
||||
* {@link #setRenderer} or the `renderer` constructor option.
|
||||
* @return {module:ol/style/Style~RenderFunction|null} Custom renderer function.
|
||||
* @api
|
||||
*/
|
||||
Style.prototype.getRenderer = function() {
|
||||
return this.renderer_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets a custom renderer function for this style. When set, `fill`, `stroke`
|
||||
* and `image` options of the style will be ignored.
|
||||
* @param {module:ol/style/Style~RenderFunction|null} renderer Custom renderer function.
|
||||
* @api
|
||||
*/
|
||||
Style.prototype.setRenderer = function(renderer) {
|
||||
this.renderer_ = renderer;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the geometry to be rendered.
|
||||
* @return {string|module:ol/geom/Geometry|module:ol/style/Style~GeometryFunction}
|
||||
* Feature property or geometry or function that returns the geometry that will
|
||||
* be rendered with this style.
|
||||
* @api
|
||||
*/
|
||||
Style.prototype.getGeometry = function() {
|
||||
return this.geometry_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the function used to generate a geometry for rendering.
|
||||
* @return {!module:ol/style/Style~GeometryFunction} Function that is called with a feature
|
||||
* and returns the geometry to render instead of the feature's geometry.
|
||||
* @api
|
||||
*/
|
||||
Style.prototype.getGeometryFunction = function() {
|
||||
return this.geometryFunction_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the fill style.
|
||||
* @return {module:ol/style/Fill} Fill style.
|
||||
* @api
|
||||
*/
|
||||
Style.prototype.getFill = function() {
|
||||
return this.fill_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the fill style.
|
||||
* @param {module:ol/style/Fill} fill Fill style.
|
||||
* @api
|
||||
*/
|
||||
Style.prototype.setFill = function(fill) {
|
||||
this.fill_ = fill;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the image style.
|
||||
* @return {module:ol/style/Image} Image style.
|
||||
* @api
|
||||
*/
|
||||
Style.prototype.getImage = function() {
|
||||
return this.image_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the image style.
|
||||
* @param {module:ol/style/Image} image Image style.
|
||||
* @api
|
||||
*/
|
||||
Style.prototype.setImage = function(image) {
|
||||
this.image_ = image;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the stroke style.
|
||||
* @return {module:ol/style/Stroke} Stroke style.
|
||||
* @api
|
||||
*/
|
||||
Style.prototype.getStroke = function() {
|
||||
return this.stroke_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the stroke style.
|
||||
* @param {module:ol/style/Stroke} stroke Stroke style.
|
||||
* @api
|
||||
*/
|
||||
Style.prototype.setStroke = function(stroke) {
|
||||
this.stroke_ = stroke;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the text style.
|
||||
* @return {module:ol/style/Text} Text style.
|
||||
* @api
|
||||
*/
|
||||
Style.prototype.getText = function() {
|
||||
return this.text_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the text style.
|
||||
* @param {module:ol/style/Text} text Text style.
|
||||
* @api
|
||||
*/
|
||||
Style.prototype.setText = function(text) {
|
||||
this.text_ = text;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the z-index for the style.
|
||||
* @return {number|undefined} ZIndex.
|
||||
* @api
|
||||
*/
|
||||
Style.prototype.getZIndex = function() {
|
||||
return this.zIndex_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set a geometry that is rendered instead of the feature's geometry.
|
||||
*
|
||||
* @param {string|module:ol/geom/Geometry|module:ol/style/Style~GeometryFunction} geometry
|
||||
* Feature property or geometry or function returning a geometry to render
|
||||
* for this style.
|
||||
* @api
|
||||
*/
|
||||
Style.prototype.setGeometry = function(geometry) {
|
||||
if (typeof geometry === 'function') {
|
||||
this.geometryFunction_ = geometry;
|
||||
} else if (typeof geometry === 'string') {
|
||||
this.geometryFunction_ = function(feature) {
|
||||
return (
|
||||
/** @type {module:ol/geom/Geometry} */ (feature.get(geometry))
|
||||
);
|
||||
};
|
||||
} else if (!geometry) {
|
||||
/**
|
||||
* @private
|
||||
* @type {!module:ol/style/Style~GeometryFunction}
|
||||
*/
|
||||
this.geometryFunction_ = defaultGeometryFunction;
|
||||
} else if (geometry !== undefined) {
|
||||
this.geometryFunction_ = function() {
|
||||
return (
|
||||
/** @type {module:ol/geom/Geometry} */ (geometry)
|
||||
);
|
||||
};
|
||||
|
||||
if (options.geometry !== undefined) {
|
||||
this.setGeometry(options.geometry);
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/style/Fill}
|
||||
*/
|
||||
this.fill_ = options.fill !== undefined ? options.fill : null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/style/Image}
|
||||
*/
|
||||
this.image_ = options.image !== undefined ? options.image : null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/style/Style~RenderFunction|null}
|
||||
*/
|
||||
this.renderer_ = options.renderer !== undefined ? options.renderer : null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/style/Stroke}
|
||||
*/
|
||||
this.stroke_ = options.stroke !== undefined ? options.stroke : null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/style/Text}
|
||||
*/
|
||||
this.text_ = options.text !== undefined ? options.text : null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number|undefined}
|
||||
*/
|
||||
this.zIndex_ = options.zIndex;
|
||||
|
||||
}
|
||||
this.geometry_ = geometry;
|
||||
};
|
||||
|
||||
/**
|
||||
* Clones the style.
|
||||
* @return {module:ol/style/Style} The cloned style.
|
||||
* @api
|
||||
*/
|
||||
clone() {
|
||||
let geometry = this.getGeometry();
|
||||
if (geometry && geometry.clone) {
|
||||
geometry = geometry.clone();
|
||||
}
|
||||
return new Style({
|
||||
geometry: geometry,
|
||||
fill: this.getFill() ? this.getFill().clone() : undefined,
|
||||
image: this.getImage() ? this.getImage().clone() : undefined,
|
||||
stroke: this.getStroke() ? this.getStroke().clone() : undefined,
|
||||
text: this.getText() ? this.getText().clone() : undefined,
|
||||
zIndex: this.getZIndex()
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the z-index.
|
||||
*
|
||||
* @param {number|undefined} zIndex ZIndex.
|
||||
* @api
|
||||
*/
|
||||
Style.prototype.setZIndex = function(zIndex) {
|
||||
this.zIndex_ = zIndex;
|
||||
};
|
||||
/**
|
||||
* Get the custom renderer function that was configured with
|
||||
* {@link #setRenderer} or the `renderer` constructor option.
|
||||
* @return {module:ol/style/Style~RenderFunction|null} Custom renderer function.
|
||||
* @api
|
||||
*/
|
||||
getRenderer() {
|
||||
return this.renderer_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a custom renderer function for this style. When set, `fill`, `stroke`
|
||||
* and `image` options of the style will be ignored.
|
||||
* @param {module:ol/style/Style~RenderFunction|null} renderer Custom renderer function.
|
||||
* @api
|
||||
*/
|
||||
setRenderer(renderer) {
|
||||
this.renderer_ = renderer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the geometry to be rendered.
|
||||
* @return {string|module:ol/geom/Geometry|module:ol/style/Style~GeometryFunction}
|
||||
* Feature property or geometry or function that returns the geometry that will
|
||||
* be rendered with this style.
|
||||
* @api
|
||||
*/
|
||||
getGeometry() {
|
||||
return this.geometry_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the function used to generate a geometry for rendering.
|
||||
* @return {!module:ol/style/Style~GeometryFunction} Function that is called with a feature
|
||||
* and returns the geometry to render instead of the feature's geometry.
|
||||
* @api
|
||||
*/
|
||||
getGeometryFunction() {
|
||||
return this.geometryFunction_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the fill style.
|
||||
* @return {module:ol/style/Fill} Fill style.
|
||||
* @api
|
||||
*/
|
||||
getFill() {
|
||||
return this.fill_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the fill style.
|
||||
* @param {module:ol/style/Fill} fill Fill style.
|
||||
* @api
|
||||
*/
|
||||
setFill(fill) {
|
||||
this.fill_ = fill;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the image style.
|
||||
* @return {module:ol/style/Image} Image style.
|
||||
* @api
|
||||
*/
|
||||
getImage() {
|
||||
return this.image_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the image style.
|
||||
* @param {module:ol/style/Image} image Image style.
|
||||
* @api
|
||||
*/
|
||||
setImage(image) {
|
||||
this.image_ = image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the stroke style.
|
||||
* @return {module:ol/style/Stroke} Stroke style.
|
||||
* @api
|
||||
*/
|
||||
getStroke() {
|
||||
return this.stroke_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the stroke style.
|
||||
* @param {module:ol/style/Stroke} stroke Stroke style.
|
||||
* @api
|
||||
*/
|
||||
setStroke(stroke) {
|
||||
this.stroke_ = stroke;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the text style.
|
||||
* @return {module:ol/style/Text} Text style.
|
||||
* @api
|
||||
*/
|
||||
getText() {
|
||||
return this.text_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the text style.
|
||||
* @param {module:ol/style/Text} text Text style.
|
||||
* @api
|
||||
*/
|
||||
setText(text) {
|
||||
this.text_ = text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the z-index for the style.
|
||||
* @return {number|undefined} ZIndex.
|
||||
* @api
|
||||
*/
|
||||
getZIndex() {
|
||||
return this.zIndex_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a geometry that is rendered instead of the feature's geometry.
|
||||
*
|
||||
* @param {string|module:ol/geom/Geometry|module:ol/style/Style~GeometryFunction} geometry
|
||||
* Feature property or geometry or function returning a geometry to render
|
||||
* for this style.
|
||||
* @api
|
||||
*/
|
||||
setGeometry(geometry) {
|
||||
if (typeof geometry === 'function') {
|
||||
this.geometryFunction_ = geometry;
|
||||
} else if (typeof geometry === 'string') {
|
||||
this.geometryFunction_ = function(feature) {
|
||||
return (
|
||||
/** @type {module:ol/geom/Geometry} */ (feature.get(geometry))
|
||||
);
|
||||
};
|
||||
} else if (!geometry) {
|
||||
this.geometryFunction_ = defaultGeometryFunction;
|
||||
} else if (geometry !== undefined) {
|
||||
this.geometryFunction_ = function() {
|
||||
return (
|
||||
/** @type {module:ol/geom/Geometry} */ (geometry)
|
||||
);
|
||||
};
|
||||
}
|
||||
this.geometry_ = geometry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the z-index.
|
||||
*
|
||||
* @param {number|undefined} zIndex ZIndex.
|
||||
* @api
|
||||
*/
|
||||
setZIndex(zIndex) {
|
||||
this.zIndex_ = zIndex;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -53,484 +53,453 @@ const DEFAULT_FILL_COLOR = '#333';
|
||||
* @param {module:ol/style/Text~Options=} opt_options Options.
|
||||
* @api
|
||||
*/
|
||||
const Text = function(opt_options) {
|
||||
|
||||
const options = opt_options || {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {string|undefined}
|
||||
*/
|
||||
this.font_ = options.font;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number|undefined}
|
||||
*/
|
||||
this.rotation_ = options.rotation;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean|undefined}
|
||||
*/
|
||||
this.rotateWithView_ = options.rotateWithView;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number|undefined}
|
||||
*/
|
||||
this.scale_ = options.scale;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {string|undefined}
|
||||
*/
|
||||
this.text_ = options.text;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {string|undefined}
|
||||
*/
|
||||
this.textAlign_ = options.textAlign;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {string|undefined}
|
||||
*/
|
||||
this.textBaseline_ = options.textBaseline;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/style/Fill}
|
||||
*/
|
||||
this.fill_ = options.fill !== undefined ? options.fill :
|
||||
new Fill({color: DEFAULT_FILL_COLOR});
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.maxAngle_ = options.maxAngle !== undefined ? options.maxAngle : Math.PI / 4;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/style/TextPlacement|string}
|
||||
*/
|
||||
this.placement_ = options.placement !== undefined ? options.placement : TextPlacement.POINT;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.overflow_ = !!options.overflow;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/style/Stroke}
|
||||
*/
|
||||
this.stroke_ = options.stroke !== undefined ? options.stroke : null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.offsetX_ = options.offsetX !== undefined ? options.offsetX : 0;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.offsetY_ = options.offsetY !== undefined ? options.offsetY : 0;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/style/Fill}
|
||||
*/
|
||||
this.backgroundFill_ = options.backgroundFill ? options.backgroundFill : null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/style/Stroke}
|
||||
*/
|
||||
this.backgroundStroke_ = options.backgroundStroke ? options.backgroundStroke : null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<number>}
|
||||
*/
|
||||
this.padding_ = options.padding === undefined ? null : options.padding;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Clones the style.
|
||||
* @return {module:ol/style/Text} The cloned style.
|
||||
* @api
|
||||
*/
|
||||
Text.prototype.clone = function() {
|
||||
return new Text({
|
||||
font: this.getFont(),
|
||||
placement: this.getPlacement(),
|
||||
maxAngle: this.getMaxAngle(),
|
||||
overflow: this.getOverflow(),
|
||||
rotation: this.getRotation(),
|
||||
rotateWithView: this.getRotateWithView(),
|
||||
scale: this.getScale(),
|
||||
text: this.getText(),
|
||||
textAlign: this.getTextAlign(),
|
||||
textBaseline: this.getTextBaseline(),
|
||||
fill: this.getFill() ? this.getFill().clone() : undefined,
|
||||
stroke: this.getStroke() ? this.getStroke().clone() : undefined,
|
||||
offsetX: this.getOffsetX(),
|
||||
offsetY: this.getOffsetY(),
|
||||
backgroundFill: this.getBackgroundFill() ? this.getBackgroundFill().clone() : undefined,
|
||||
backgroundStroke: this.getBackgroundStroke() ? this.getBackgroundStroke().clone() : undefined
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the `overflow` configuration.
|
||||
* @return {boolean} Let text overflow the length of the path they follow.
|
||||
* @api
|
||||
*/
|
||||
Text.prototype.getOverflow = function() {
|
||||
return this.overflow_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the font name.
|
||||
* @return {string|undefined} Font.
|
||||
* @api
|
||||
*/
|
||||
Text.prototype.getFont = function() {
|
||||
return this.font_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the maximum angle between adjacent characters.
|
||||
* @return {number} Angle in radians.
|
||||
* @api
|
||||
*/
|
||||
Text.prototype.getMaxAngle = function() {
|
||||
return this.maxAngle_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the label placement.
|
||||
* @return {module:ol/style/TextPlacement|string} Text placement.
|
||||
* @api
|
||||
*/
|
||||
Text.prototype.getPlacement = function() {
|
||||
return this.placement_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the x-offset for the text.
|
||||
* @return {number} Horizontal text offset.
|
||||
* @api
|
||||
*/
|
||||
Text.prototype.getOffsetX = function() {
|
||||
return this.offsetX_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the y-offset for the text.
|
||||
* @return {number} Vertical text offset.
|
||||
* @api
|
||||
*/
|
||||
Text.prototype.getOffsetY = function() {
|
||||
return this.offsetY_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the fill style for the text.
|
||||
* @return {module:ol/style/Fill} Fill style.
|
||||
* @api
|
||||
*/
|
||||
Text.prototype.getFill = function() {
|
||||
return this.fill_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Determine whether the text rotates with the map.
|
||||
* @return {boolean|undefined} Rotate with map.
|
||||
* @api
|
||||
*/
|
||||
Text.prototype.getRotateWithView = function() {
|
||||
return this.rotateWithView_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the text rotation.
|
||||
* @return {number|undefined} Rotation.
|
||||
* @api
|
||||
*/
|
||||
Text.prototype.getRotation = function() {
|
||||
return this.rotation_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the text scale.
|
||||
* @return {number|undefined} Scale.
|
||||
* @api
|
||||
*/
|
||||
Text.prototype.getScale = function() {
|
||||
return this.scale_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the stroke style for the text.
|
||||
* @return {module:ol/style/Stroke} Stroke style.
|
||||
* @api
|
||||
*/
|
||||
Text.prototype.getStroke = function() {
|
||||
return this.stroke_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the text to be rendered.
|
||||
* @return {string|undefined} Text.
|
||||
* @api
|
||||
*/
|
||||
Text.prototype.getText = function() {
|
||||
return this.text_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the text alignment.
|
||||
* @return {string|undefined} Text align.
|
||||
* @api
|
||||
*/
|
||||
Text.prototype.getTextAlign = function() {
|
||||
return this.textAlign_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the text baseline.
|
||||
* @return {string|undefined} Text baseline.
|
||||
* @api
|
||||
*/
|
||||
Text.prototype.getTextBaseline = function() {
|
||||
return this.textBaseline_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the background fill style for the text.
|
||||
* @return {module:ol/style/Fill} Fill style.
|
||||
* @api
|
||||
*/
|
||||
Text.prototype.getBackgroundFill = function() {
|
||||
return this.backgroundFill_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the background stroke style for the text.
|
||||
* @return {module:ol/style/Stroke} Stroke style.
|
||||
* @api
|
||||
*/
|
||||
Text.prototype.getBackgroundStroke = function() {
|
||||
return this.backgroundStroke_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the padding for the text.
|
||||
* @return {Array.<number>} Padding.
|
||||
* @api
|
||||
*/
|
||||
Text.prototype.getPadding = function() {
|
||||
return this.padding_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the `overflow` property.
|
||||
*
|
||||
* @param {boolean} overflow Let text overflow the path that it follows.
|
||||
* @api
|
||||
*/
|
||||
Text.prototype.setOverflow = function(overflow) {
|
||||
this.overflow_ = overflow;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the font.
|
||||
*
|
||||
* @param {string|undefined} font Font.
|
||||
* @api
|
||||
*/
|
||||
Text.prototype.setFont = function(font) {
|
||||
this.font_ = font;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the maximum angle between adjacent characters.
|
||||
*
|
||||
* @param {number} maxAngle Angle in radians.
|
||||
* @api
|
||||
*/
|
||||
Text.prototype.setMaxAngle = function(maxAngle) {
|
||||
this.maxAngle_ = maxAngle;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the x offset.
|
||||
*
|
||||
* @param {number} offsetX Horizontal text offset.
|
||||
* @api
|
||||
*/
|
||||
Text.prototype.setOffsetX = function(offsetX) {
|
||||
this.offsetX_ = offsetX;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the y offset.
|
||||
*
|
||||
* @param {number} offsetY Vertical text offset.
|
||||
* @api
|
||||
*/
|
||||
Text.prototype.setOffsetY = function(offsetY) {
|
||||
this.offsetY_ = offsetY;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the text placement.
|
||||
*
|
||||
* @param {module:ol/style/TextPlacement|string} placement Placement.
|
||||
* @api
|
||||
*/
|
||||
Text.prototype.setPlacement = function(placement) {
|
||||
this.placement_ = placement;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the fill.
|
||||
*
|
||||
* @param {module:ol/style/Fill} fill Fill style.
|
||||
* @api
|
||||
*/
|
||||
Text.prototype.setFill = function(fill) {
|
||||
this.fill_ = fill;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the rotation.
|
||||
*
|
||||
* @param {number|undefined} rotation Rotation.
|
||||
* @api
|
||||
*/
|
||||
Text.prototype.setRotation = function(rotation) {
|
||||
this.rotation_ = rotation;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the scale.
|
||||
*
|
||||
* @param {number|undefined} scale Scale.
|
||||
* @api
|
||||
*/
|
||||
Text.prototype.setScale = function(scale) {
|
||||
this.scale_ = scale;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the stroke.
|
||||
*
|
||||
* @param {module:ol/style/Stroke} stroke Stroke style.
|
||||
* @api
|
||||
*/
|
||||
Text.prototype.setStroke = function(stroke) {
|
||||
this.stroke_ = stroke;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the text.
|
||||
*
|
||||
* @param {string|undefined} text Text.
|
||||
* @api
|
||||
*/
|
||||
Text.prototype.setText = function(text) {
|
||||
this.text_ = text;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the text alignment.
|
||||
*
|
||||
* @param {string|undefined} textAlign Text align.
|
||||
* @api
|
||||
*/
|
||||
Text.prototype.setTextAlign = function(textAlign) {
|
||||
this.textAlign_ = textAlign;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the text baseline.
|
||||
*
|
||||
* @param {string|undefined} textBaseline Text baseline.
|
||||
* @api
|
||||
*/
|
||||
Text.prototype.setTextBaseline = function(textBaseline) {
|
||||
this.textBaseline_ = textBaseline;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the background fill.
|
||||
*
|
||||
* @param {module:ol/style/Fill} fill Fill style.
|
||||
* @api
|
||||
*/
|
||||
Text.prototype.setBackgroundFill = function(fill) {
|
||||
this.backgroundFill_ = fill;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the background stroke.
|
||||
*
|
||||
* @param {module:ol/style/Stroke} stroke Stroke style.
|
||||
* @api
|
||||
*/
|
||||
Text.prototype.setBackgroundStroke = function(stroke) {
|
||||
this.backgroundStroke_ = stroke;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the padding (`[top, right, bottom, left]`).
|
||||
*
|
||||
* @param {!Array.<number>} padding Padding.
|
||||
* @api
|
||||
*/
|
||||
Text.prototype.setPadding = function(padding) {
|
||||
this.padding_ = padding;
|
||||
};
|
||||
class Text {
|
||||
constructor(opt_options) {
|
||||
|
||||
const options = opt_options || {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {string|undefined}
|
||||
*/
|
||||
this.font_ = options.font;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number|undefined}
|
||||
*/
|
||||
this.rotation_ = options.rotation;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean|undefined}
|
||||
*/
|
||||
this.rotateWithView_ = options.rotateWithView;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number|undefined}
|
||||
*/
|
||||
this.scale_ = options.scale;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {string|undefined}
|
||||
*/
|
||||
this.text_ = options.text;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {string|undefined}
|
||||
*/
|
||||
this.textAlign_ = options.textAlign;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {string|undefined}
|
||||
*/
|
||||
this.textBaseline_ = options.textBaseline;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/style/Fill}
|
||||
*/
|
||||
this.fill_ = options.fill !== undefined ? options.fill :
|
||||
new Fill({color: DEFAULT_FILL_COLOR});
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.maxAngle_ = options.maxAngle !== undefined ? options.maxAngle : Math.PI / 4;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/style/TextPlacement|string}
|
||||
*/
|
||||
this.placement_ = options.placement !== undefined ? options.placement : TextPlacement.POINT;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.overflow_ = !!options.overflow;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/style/Stroke}
|
||||
*/
|
||||
this.stroke_ = options.stroke !== undefined ? options.stroke : null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.offsetX_ = options.offsetX !== undefined ? options.offsetX : 0;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.offsetY_ = options.offsetY !== undefined ? options.offsetY : 0;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/style/Fill}
|
||||
*/
|
||||
this.backgroundFill_ = options.backgroundFill ? options.backgroundFill : null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {module:ol/style/Stroke}
|
||||
*/
|
||||
this.backgroundStroke_ = options.backgroundStroke ? options.backgroundStroke : null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<number>}
|
||||
*/
|
||||
this.padding_ = options.padding === undefined ? null : options.padding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clones the style.
|
||||
* @return {module:ol/style/Text} The cloned style.
|
||||
* @api
|
||||
*/
|
||||
clone() {
|
||||
return new Text({
|
||||
font: this.getFont(),
|
||||
placement: this.getPlacement(),
|
||||
maxAngle: this.getMaxAngle(),
|
||||
overflow: this.getOverflow(),
|
||||
rotation: this.getRotation(),
|
||||
rotateWithView: this.getRotateWithView(),
|
||||
scale: this.getScale(),
|
||||
text: this.getText(),
|
||||
textAlign: this.getTextAlign(),
|
||||
textBaseline: this.getTextBaseline(),
|
||||
fill: this.getFill() ? this.getFill().clone() : undefined,
|
||||
stroke: this.getStroke() ? this.getStroke().clone() : undefined,
|
||||
offsetX: this.getOffsetX(),
|
||||
offsetY: this.getOffsetY(),
|
||||
backgroundFill: this.getBackgroundFill() ? this.getBackgroundFill().clone() : undefined,
|
||||
backgroundStroke: this.getBackgroundStroke() ? this.getBackgroundStroke().clone() : undefined
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `overflow` configuration.
|
||||
* @return {boolean} Let text overflow the length of the path they follow.
|
||||
* @api
|
||||
*/
|
||||
getOverflow() {
|
||||
return this.overflow_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the font name.
|
||||
* @return {string|undefined} Font.
|
||||
* @api
|
||||
*/
|
||||
getFont() {
|
||||
return this.font_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the maximum angle between adjacent characters.
|
||||
* @return {number} Angle in radians.
|
||||
* @api
|
||||
*/
|
||||
getMaxAngle() {
|
||||
return this.maxAngle_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the label placement.
|
||||
* @return {module:ol/style/TextPlacement|string} Text placement.
|
||||
* @api
|
||||
*/
|
||||
getPlacement() {
|
||||
return this.placement_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the x-offset for the text.
|
||||
* @return {number} Horizontal text offset.
|
||||
* @api
|
||||
*/
|
||||
getOffsetX() {
|
||||
return this.offsetX_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the y-offset for the text.
|
||||
* @return {number} Vertical text offset.
|
||||
* @api
|
||||
*/
|
||||
getOffsetY() {
|
||||
return this.offsetY_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the fill style for the text.
|
||||
* @return {module:ol/style/Fill} Fill style.
|
||||
* @api
|
||||
*/
|
||||
getFill() {
|
||||
return this.fill_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the text rotates with the map.
|
||||
* @return {boolean|undefined} Rotate with map.
|
||||
* @api
|
||||
*/
|
||||
getRotateWithView() {
|
||||
return this.rotateWithView_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the text rotation.
|
||||
* @return {number|undefined} Rotation.
|
||||
* @api
|
||||
*/
|
||||
getRotation() {
|
||||
return this.rotation_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the text scale.
|
||||
* @return {number|undefined} Scale.
|
||||
* @api
|
||||
*/
|
||||
getScale() {
|
||||
return this.scale_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the stroke style for the text.
|
||||
* @return {module:ol/style/Stroke} Stroke style.
|
||||
* @api
|
||||
*/
|
||||
getStroke() {
|
||||
return this.stroke_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the text to be rendered.
|
||||
* @return {string|undefined} Text.
|
||||
* @api
|
||||
*/
|
||||
getText() {
|
||||
return this.text_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the text alignment.
|
||||
* @return {string|undefined} Text align.
|
||||
* @api
|
||||
*/
|
||||
getTextAlign() {
|
||||
return this.textAlign_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the text baseline.
|
||||
* @return {string|undefined} Text baseline.
|
||||
* @api
|
||||
*/
|
||||
getTextBaseline() {
|
||||
return this.textBaseline_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the background fill style for the text.
|
||||
* @return {module:ol/style/Fill} Fill style.
|
||||
* @api
|
||||
*/
|
||||
getBackgroundFill() {
|
||||
return this.backgroundFill_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the background stroke style for the text.
|
||||
* @return {module:ol/style/Stroke} Stroke style.
|
||||
* @api
|
||||
*/
|
||||
getBackgroundStroke() {
|
||||
return this.backgroundStroke_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the padding for the text.
|
||||
* @return {Array.<number>} Padding.
|
||||
* @api
|
||||
*/
|
||||
getPadding() {
|
||||
return this.padding_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the `overflow` property.
|
||||
*
|
||||
* @param {boolean} overflow Let text overflow the path that it follows.
|
||||
* @api
|
||||
*/
|
||||
setOverflow(overflow) {
|
||||
this.overflow_ = overflow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the font.
|
||||
*
|
||||
* @param {string|undefined} font Font.
|
||||
* @api
|
||||
*/
|
||||
setFont(font) {
|
||||
this.font_ = font;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the maximum angle between adjacent characters.
|
||||
*
|
||||
* @param {number} maxAngle Angle in radians.
|
||||
* @api
|
||||
*/
|
||||
setMaxAngle(maxAngle) {
|
||||
this.maxAngle_ = maxAngle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the x offset.
|
||||
*
|
||||
* @param {number} offsetX Horizontal text offset.
|
||||
* @api
|
||||
*/
|
||||
setOffsetX(offsetX) {
|
||||
this.offsetX_ = offsetX;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the y offset.
|
||||
*
|
||||
* @param {number} offsetY Vertical text offset.
|
||||
* @api
|
||||
*/
|
||||
setOffsetY(offsetY) {
|
||||
this.offsetY_ = offsetY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the text placement.
|
||||
*
|
||||
* @param {module:ol/style/TextPlacement|string} placement Placement.
|
||||
* @api
|
||||
*/
|
||||
setPlacement(placement) {
|
||||
this.placement_ = placement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the fill.
|
||||
*
|
||||
* @param {module:ol/style/Fill} fill Fill style.
|
||||
* @api
|
||||
*/
|
||||
setFill(fill) {
|
||||
this.fill_ = fill;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the rotation.
|
||||
*
|
||||
* @param {number|undefined} rotation Rotation.
|
||||
* @api
|
||||
*/
|
||||
setRotation(rotation) {
|
||||
this.rotation_ = rotation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the scale.
|
||||
*
|
||||
* @param {number|undefined} scale Scale.
|
||||
* @api
|
||||
*/
|
||||
setScale(scale) {
|
||||
this.scale_ = scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the stroke.
|
||||
*
|
||||
* @param {module:ol/style/Stroke} stroke Stroke style.
|
||||
* @api
|
||||
*/
|
||||
setStroke(stroke) {
|
||||
this.stroke_ = stroke;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the text.
|
||||
*
|
||||
* @param {string|undefined} text Text.
|
||||
* @api
|
||||
*/
|
||||
setText(text) {
|
||||
this.text_ = text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the text alignment.
|
||||
*
|
||||
* @param {string|undefined} textAlign Text align.
|
||||
* @api
|
||||
*/
|
||||
setTextAlign(textAlign) {
|
||||
this.textAlign_ = textAlign;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the text baseline.
|
||||
*
|
||||
* @param {string|undefined} textBaseline Text baseline.
|
||||
* @api
|
||||
*/
|
||||
setTextBaseline(textBaseline) {
|
||||
this.textBaseline_ = textBaseline;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the background fill.
|
||||
*
|
||||
* @param {module:ol/style/Fill} fill Fill style.
|
||||
* @api
|
||||
*/
|
||||
setBackgroundFill(fill) {
|
||||
this.backgroundFill_ = fill;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the background stroke.
|
||||
*
|
||||
* @param {module:ol/style/Stroke} stroke Stroke style.
|
||||
* @api
|
||||
*/
|
||||
setBackgroundStroke(stroke) {
|
||||
this.backgroundStroke_ = stroke;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the padding (`[top, right, bottom, left]`).
|
||||
*
|
||||
* @param {!Array.<number>} padding Padding.
|
||||
* @api
|
||||
*/
|
||||
setPadding(padding) {
|
||||
this.padding_ = padding;
|
||||
}
|
||||
}
|
||||
|
||||
export default Text;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -55,46 +55,47 @@ import TileGrid from '../tilegrid/TileGrid.js';
|
||||
* @struct
|
||||
* @api
|
||||
*/
|
||||
const WMTSTileGrid = function(options) {
|
||||
/**
|
||||
* @private
|
||||
* @type {!Array.<string>}
|
||||
*/
|
||||
this.matrixIds_ = options.matrixIds;
|
||||
// FIXME: should the matrixIds become optional?
|
||||
class WMTSTileGrid {
|
||||
constructor(options) {
|
||||
/**
|
||||
* @private
|
||||
* @type {!Array.<string>}
|
||||
*/
|
||||
this.matrixIds_ = options.matrixIds;
|
||||
// FIXME: should the matrixIds become optional?
|
||||
|
||||
TileGrid.call(this, {
|
||||
extent: options.extent,
|
||||
origin: options.origin,
|
||||
origins: options.origins,
|
||||
resolutions: options.resolutions,
|
||||
tileSize: options.tileSize,
|
||||
tileSizes: options.tileSizes,
|
||||
sizes: options.sizes
|
||||
});
|
||||
};
|
||||
TileGrid.call(this, {
|
||||
extent: options.extent,
|
||||
origin: options.origin,
|
||||
origins: options.origins,
|
||||
resolutions: options.resolutions,
|
||||
tileSize: options.tileSize,
|
||||
tileSizes: options.tileSizes,
|
||||
sizes: options.sizes
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} z Z.
|
||||
* @return {string} MatrixId..
|
||||
*/
|
||||
getMatrixId(z) {
|
||||
return this.matrixIds_[z];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of matrix identifiers.
|
||||
* @return {Array.<string>} MatrixIds.
|
||||
* @api
|
||||
*/
|
||||
getMatrixIds() {
|
||||
return this.matrixIds_;
|
||||
}
|
||||
}
|
||||
|
||||
inherits(WMTSTileGrid, TileGrid);
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} z Z.
|
||||
* @return {string} MatrixId..
|
||||
*/
|
||||
WMTSTileGrid.prototype.getMatrixId = function(z) {
|
||||
return this.matrixIds_[z];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the list of matrix identifiers.
|
||||
* @return {Array.<string>} MatrixIds.
|
||||
* @api
|
||||
*/
|
||||
WMTSTileGrid.prototype.getMatrixIds = function() {
|
||||
return this.matrixIds_;
|
||||
};
|
||||
|
||||
export default WMTSTileGrid;
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,36 +18,36 @@ const BufferUsage = {
|
||||
* @param {number=} opt_usage Usage.
|
||||
* @struct
|
||||
*/
|
||||
const WebGLBuffer = function(opt_arr, opt_usage) {
|
||||
class WebGLBuffer {
|
||||
constructor(opt_arr, opt_usage) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<number>}
|
||||
*/
|
||||
this.arr_ = opt_arr !== undefined ? opt_arr : [];
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<number>}
|
||||
*/
|
||||
this.arr_ = opt_arr !== undefined ? opt_arr : [];
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.usage_ = opt_usage !== undefined ? opt_usage : BufferUsage.STATIC_DRAW;
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.usage_ = opt_usage !== undefined ? opt_usage : BufferUsage.STATIC_DRAW;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {Array.<number>} Array.
|
||||
*/
|
||||
getArray() {
|
||||
return this.arr_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {Array.<number>} Array.
|
||||
*/
|
||||
WebGLBuffer.prototype.getArray = function() {
|
||||
return this.arr_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} Usage.
|
||||
*/
|
||||
WebGLBuffer.prototype.getUsage = function() {
|
||||
return this.usage_;
|
||||
};
|
||||
/**
|
||||
* @return {number} Usage.
|
||||
*/
|
||||
getUsage() {
|
||||
return this.usage_;
|
||||
}
|
||||
}
|
||||
|
||||
export default WebGLBuffer;
|
||||
|
||||
@@ -27,295 +27,285 @@ import ContextEventType from '../webgl/ContextEventType.js';
|
||||
* @param {HTMLCanvasElement} canvas Canvas.
|
||||
* @param {WebGLRenderingContext} gl GL.
|
||||
*/
|
||||
const WebGLContext = function(canvas, gl) {
|
||||
class WebGLContext {
|
||||
constructor(canvas, gl) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {HTMLCanvasElement}
|
||||
*/
|
||||
this.canvas_ = canvas;
|
||||
/**
|
||||
* @private
|
||||
* @type {HTMLCanvasElement}
|
||||
*/
|
||||
this.canvas_ = canvas;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {WebGLRenderingContext}
|
||||
*/
|
||||
this.gl_ = gl;
|
||||
/**
|
||||
* @private
|
||||
* @type {WebGLRenderingContext}
|
||||
*/
|
||||
this.gl_ = gl;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {!Object.<string, module:ol/webgl/Context~BufferCacheEntry>}
|
||||
*/
|
||||
this.bufferCache_ = {};
|
||||
/**
|
||||
* @private
|
||||
* @type {!Object.<string, module:ol/webgl/Context~BufferCacheEntry>}
|
||||
*/
|
||||
this.bufferCache_ = {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {!Object.<string, WebGLShader>}
|
||||
*/
|
||||
this.shaderCache_ = {};
|
||||
/**
|
||||
* @private
|
||||
* @type {!Object.<string, WebGLShader>}
|
||||
*/
|
||||
this.shaderCache_ = {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {!Object.<string, WebGLProgram>}
|
||||
*/
|
||||
this.programCache_ = {};
|
||||
/**
|
||||
* @private
|
||||
* @type {!Object.<string, WebGLProgram>}
|
||||
*/
|
||||
this.programCache_ = {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {WebGLProgram}
|
||||
*/
|
||||
this.currentProgram_ = null;
|
||||
/**
|
||||
* @private
|
||||
* @type {WebGLProgram}
|
||||
*/
|
||||
this.currentProgram_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {WebGLFramebuffer}
|
||||
*/
|
||||
this.hitDetectionFramebuffer_ = null;
|
||||
/**
|
||||
* @private
|
||||
* @type {WebGLFramebuffer}
|
||||
*/
|
||||
this.hitDetectionFramebuffer_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {WebGLTexture}
|
||||
*/
|
||||
this.hitDetectionTexture_ = null;
|
||||
/**
|
||||
* @private
|
||||
* @type {WebGLTexture}
|
||||
*/
|
||||
this.hitDetectionTexture_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {WebGLRenderbuffer}
|
||||
*/
|
||||
this.hitDetectionRenderbuffer_ = null;
|
||||
/**
|
||||
* @private
|
||||
* @type {WebGLRenderbuffer}
|
||||
*/
|
||||
this.hitDetectionRenderbuffer_ = null;
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.hasOESElementIndexUint = includes(WEBGL_EXTENSIONS, 'OES_element_index_uint');
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.hasOESElementIndexUint = includes(WEBGL_EXTENSIONS, 'OES_element_index_uint');
|
||||
|
||||
// use the OES_element_index_uint extension if available
|
||||
if (this.hasOESElementIndexUint) {
|
||||
gl.getExtension('OES_element_index_uint');
|
||||
}
|
||||
|
||||
listen(this.canvas_, ContextEventType.LOST,
|
||||
this.handleWebGLContextLost, this);
|
||||
listen(this.canvas_, ContextEventType.RESTORED,
|
||||
this.handleWebGLContextRestored, this);
|
||||
|
||||
// use the OES_element_index_uint extension if available
|
||||
if (this.hasOESElementIndexUint) {
|
||||
gl.getExtension('OES_element_index_uint');
|
||||
}
|
||||
|
||||
listen(this.canvas_, ContextEventType.LOST,
|
||||
this.handleWebGLContextLost, this);
|
||||
listen(this.canvas_, ContextEventType.RESTORED,
|
||||
this.handleWebGLContextRestored, this);
|
||||
/**
|
||||
* Just bind the buffer if it's in the cache. Otherwise create
|
||||
* the WebGL buffer, bind it, populate it, and add an entry to
|
||||
* the cache.
|
||||
* @param {number} target Target.
|
||||
* @param {module:ol/webgl/Buffer} buf Buffer.
|
||||
*/
|
||||
bindBuffer(target, buf) {
|
||||
const gl = this.getGL();
|
||||
const arr = buf.getArray();
|
||||
const bufferKey = String(getUid(buf));
|
||||
if (bufferKey in this.bufferCache_) {
|
||||
const bufferCacheEntry = this.bufferCache_[bufferKey];
|
||||
gl.bindBuffer(target, bufferCacheEntry.buffer);
|
||||
} else {
|
||||
const buffer = gl.createBuffer();
|
||||
gl.bindBuffer(target, buffer);
|
||||
let /** @type {ArrayBufferView} */ arrayBuffer;
|
||||
if (target == ARRAY_BUFFER) {
|
||||
arrayBuffer = new Float32Array(arr);
|
||||
} else if (target == ELEMENT_ARRAY_BUFFER) {
|
||||
arrayBuffer = this.hasOESElementIndexUint ?
|
||||
new Uint32Array(arr) : new Uint16Array(arr);
|
||||
}
|
||||
gl.bufferData(target, arrayBuffer, buf.getUsage());
|
||||
this.bufferCache_[bufferKey] = {
|
||||
buf: buf,
|
||||
buffer: buffer
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
/**
|
||||
* @param {module:ol/webgl/Buffer} buf Buffer.
|
||||
*/
|
||||
deleteBuffer(buf) {
|
||||
const gl = this.getGL();
|
||||
const bufferKey = String(getUid(buf));
|
||||
const bufferCacheEntry = this.bufferCache_[bufferKey];
|
||||
if (!gl.isContextLost()) {
|
||||
gl.deleteBuffer(bufferCacheEntry.buffer);
|
||||
}
|
||||
delete this.bufferCache_[bufferKey];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
disposeInternal() {
|
||||
unlistenAll(this.canvas_);
|
||||
const gl = this.getGL();
|
||||
if (!gl.isContextLost()) {
|
||||
for (const key in this.bufferCache_) {
|
||||
gl.deleteBuffer(this.bufferCache_[key].buffer);
|
||||
}
|
||||
for (const key in this.programCache_) {
|
||||
gl.deleteProgram(this.programCache_[key]);
|
||||
}
|
||||
for (const key in this.shaderCache_) {
|
||||
gl.deleteShader(this.shaderCache_[key]);
|
||||
}
|
||||
// delete objects for hit-detection
|
||||
gl.deleteFramebuffer(this.hitDetectionFramebuffer_);
|
||||
gl.deleteRenderbuffer(this.hitDetectionRenderbuffer_);
|
||||
gl.deleteTexture(this.hitDetectionTexture_);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {HTMLCanvasElement} Canvas.
|
||||
*/
|
||||
getCanvas() {
|
||||
return this.canvas_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the WebGL rendering context
|
||||
* @return {WebGLRenderingContext} The rendering context.
|
||||
* @api
|
||||
*/
|
||||
getGL() {
|
||||
return this.gl_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the frame buffer for hit detection.
|
||||
* @return {WebGLFramebuffer} The hit detection frame buffer.
|
||||
*/
|
||||
getHitDetectionFramebuffer() {
|
||||
if (!this.hitDetectionFramebuffer_) {
|
||||
this.initHitDetectionFramebuffer_();
|
||||
}
|
||||
return this.hitDetectionFramebuffer_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get shader from the cache if it's in the cache. Otherwise, create
|
||||
* the WebGL shader, compile it, and add entry to cache.
|
||||
* @param {module:ol/webgl/Shader} shaderObject Shader object.
|
||||
* @return {WebGLShader} Shader.
|
||||
*/
|
||||
getShader(shaderObject) {
|
||||
const shaderKey = String(getUid(shaderObject));
|
||||
if (shaderKey in this.shaderCache_) {
|
||||
return this.shaderCache_[shaderKey];
|
||||
} else {
|
||||
const gl = this.getGL();
|
||||
const shader = gl.createShader(shaderObject.getType());
|
||||
gl.shaderSource(shader, shaderObject.getSource());
|
||||
gl.compileShader(shader);
|
||||
this.shaderCache_[shaderKey] = shader;
|
||||
return shader;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the program from the cache if it's in the cache. Otherwise create
|
||||
* the WebGL program, attach the shaders to it, and add an entry to the
|
||||
* cache.
|
||||
* @param {module:ol/webgl/Fragment} fragmentShaderObject Fragment shader.
|
||||
* @param {module:ol/webgl/Vertex} vertexShaderObject Vertex shader.
|
||||
* @return {WebGLProgram} Program.
|
||||
*/
|
||||
getProgram(fragmentShaderObject, vertexShaderObject) {
|
||||
const programKey = getUid(fragmentShaderObject) + '/' + getUid(vertexShaderObject);
|
||||
if (programKey in this.programCache_) {
|
||||
return this.programCache_[programKey];
|
||||
} else {
|
||||
const gl = this.getGL();
|
||||
const program = gl.createProgram();
|
||||
gl.attachShader(program, this.getShader(fragmentShaderObject));
|
||||
gl.attachShader(program, this.getShader(vertexShaderObject));
|
||||
gl.linkProgram(program);
|
||||
this.programCache_[programKey] = program;
|
||||
return program;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* FIXME empty description for jsdoc
|
||||
*/
|
||||
handleWebGLContextLost() {
|
||||
clear(this.bufferCache_);
|
||||
clear(this.shaderCache_);
|
||||
clear(this.programCache_);
|
||||
this.currentProgram_ = null;
|
||||
this.hitDetectionFramebuffer_ = null;
|
||||
this.hitDetectionTexture_ = null;
|
||||
this.hitDetectionRenderbuffer_ = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* FIXME empty description for jsdoc
|
||||
*/
|
||||
handleWebGLContextRestored() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a 1x1 pixel framebuffer for the hit-detection.
|
||||
* @private
|
||||
*/
|
||||
initHitDetectionFramebuffer_() {
|
||||
const gl = this.gl_;
|
||||
const framebuffer = gl.createFramebuffer();
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
|
||||
|
||||
const texture = createEmptyTexture(gl, 1, 1);
|
||||
const renderbuffer = gl.createRenderbuffer();
|
||||
gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer);
|
||||
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, 1, 1);
|
||||
gl.framebufferTexture2D(
|
||||
gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
|
||||
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT,
|
||||
gl.RENDERBUFFER, renderbuffer);
|
||||
|
||||
gl.bindTexture(gl.TEXTURE_2D, null);
|
||||
gl.bindRenderbuffer(gl.RENDERBUFFER, null);
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
||||
|
||||
this.hitDetectionFramebuffer_ = framebuffer;
|
||||
this.hitDetectionTexture_ = texture;
|
||||
this.hitDetectionRenderbuffer_ = renderbuffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use a program. If the program is already in use, this will return `false`.
|
||||
* @param {WebGLProgram} program Program.
|
||||
* @return {boolean} Changed.
|
||||
* @api
|
||||
*/
|
||||
useProgram(program) {
|
||||
if (program == this.currentProgram_) {
|
||||
return false;
|
||||
} else {
|
||||
const gl = this.getGL();
|
||||
gl.useProgram(program);
|
||||
this.currentProgram_ = program;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inherits(WebGLContext, Disposable);
|
||||
|
||||
|
||||
/**
|
||||
* Just bind the buffer if it's in the cache. Otherwise create
|
||||
* the WebGL buffer, bind it, populate it, and add an entry to
|
||||
* the cache.
|
||||
* @param {number} target Target.
|
||||
* @param {module:ol/webgl/Buffer} buf Buffer.
|
||||
*/
|
||||
WebGLContext.prototype.bindBuffer = function(target, buf) {
|
||||
const gl = this.getGL();
|
||||
const arr = buf.getArray();
|
||||
const bufferKey = String(getUid(buf));
|
||||
if (bufferKey in this.bufferCache_) {
|
||||
const bufferCacheEntry = this.bufferCache_[bufferKey];
|
||||
gl.bindBuffer(target, bufferCacheEntry.buffer);
|
||||
} else {
|
||||
const buffer = gl.createBuffer();
|
||||
gl.bindBuffer(target, buffer);
|
||||
let /** @type {ArrayBufferView} */ arrayBuffer;
|
||||
if (target == ARRAY_BUFFER) {
|
||||
arrayBuffer = new Float32Array(arr);
|
||||
} else if (target == ELEMENT_ARRAY_BUFFER) {
|
||||
arrayBuffer = this.hasOESElementIndexUint ?
|
||||
new Uint32Array(arr) : new Uint16Array(arr);
|
||||
}
|
||||
gl.bufferData(target, arrayBuffer, buf.getUsage());
|
||||
this.bufferCache_[bufferKey] = {
|
||||
buf: buf,
|
||||
buffer: buffer
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {module:ol/webgl/Buffer} buf Buffer.
|
||||
*/
|
||||
WebGLContext.prototype.deleteBuffer = function(buf) {
|
||||
const gl = this.getGL();
|
||||
const bufferKey = String(getUid(buf));
|
||||
const bufferCacheEntry = this.bufferCache_[bufferKey];
|
||||
if (!gl.isContextLost()) {
|
||||
gl.deleteBuffer(bufferCacheEntry.buffer);
|
||||
}
|
||||
delete this.bufferCache_[bufferKey];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
WebGLContext.prototype.disposeInternal = function() {
|
||||
unlistenAll(this.canvas_);
|
||||
const gl = this.getGL();
|
||||
if (!gl.isContextLost()) {
|
||||
for (const key in this.bufferCache_) {
|
||||
gl.deleteBuffer(this.bufferCache_[key].buffer);
|
||||
}
|
||||
for (const key in this.programCache_) {
|
||||
gl.deleteProgram(this.programCache_[key]);
|
||||
}
|
||||
for (const key in this.shaderCache_) {
|
||||
gl.deleteShader(this.shaderCache_[key]);
|
||||
}
|
||||
// delete objects for hit-detection
|
||||
gl.deleteFramebuffer(this.hitDetectionFramebuffer_);
|
||||
gl.deleteRenderbuffer(this.hitDetectionRenderbuffer_);
|
||||
gl.deleteTexture(this.hitDetectionTexture_);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {HTMLCanvasElement} Canvas.
|
||||
*/
|
||||
WebGLContext.prototype.getCanvas = function() {
|
||||
return this.canvas_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the WebGL rendering context
|
||||
* @return {WebGLRenderingContext} The rendering context.
|
||||
* @api
|
||||
*/
|
||||
WebGLContext.prototype.getGL = function() {
|
||||
return this.gl_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the frame buffer for hit detection.
|
||||
* @return {WebGLFramebuffer} The hit detection frame buffer.
|
||||
*/
|
||||
WebGLContext.prototype.getHitDetectionFramebuffer = function() {
|
||||
if (!this.hitDetectionFramebuffer_) {
|
||||
this.initHitDetectionFramebuffer_();
|
||||
}
|
||||
return this.hitDetectionFramebuffer_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get shader from the cache if it's in the cache. Otherwise, create
|
||||
* the WebGL shader, compile it, and add entry to cache.
|
||||
* @param {module:ol/webgl/Shader} shaderObject Shader object.
|
||||
* @return {WebGLShader} Shader.
|
||||
*/
|
||||
WebGLContext.prototype.getShader = function(shaderObject) {
|
||||
const shaderKey = String(getUid(shaderObject));
|
||||
if (shaderKey in this.shaderCache_) {
|
||||
return this.shaderCache_[shaderKey];
|
||||
} else {
|
||||
const gl = this.getGL();
|
||||
const shader = gl.createShader(shaderObject.getType());
|
||||
gl.shaderSource(shader, shaderObject.getSource());
|
||||
gl.compileShader(shader);
|
||||
this.shaderCache_[shaderKey] = shader;
|
||||
return shader;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the program from the cache if it's in the cache. Otherwise create
|
||||
* the WebGL program, attach the shaders to it, and add an entry to the
|
||||
* cache.
|
||||
* @param {module:ol/webgl/Fragment} fragmentShaderObject Fragment shader.
|
||||
* @param {module:ol/webgl/Vertex} vertexShaderObject Vertex shader.
|
||||
* @return {WebGLProgram} Program.
|
||||
*/
|
||||
WebGLContext.prototype.getProgram = function(fragmentShaderObject, vertexShaderObject) {
|
||||
const programKey = getUid(fragmentShaderObject) + '/' + getUid(vertexShaderObject);
|
||||
if (programKey in this.programCache_) {
|
||||
return this.programCache_[programKey];
|
||||
} else {
|
||||
const gl = this.getGL();
|
||||
const program = gl.createProgram();
|
||||
gl.attachShader(program, this.getShader(fragmentShaderObject));
|
||||
gl.attachShader(program, this.getShader(vertexShaderObject));
|
||||
gl.linkProgram(program);
|
||||
this.programCache_[programKey] = program;
|
||||
return program;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* FIXME empty description for jsdoc
|
||||
*/
|
||||
WebGLContext.prototype.handleWebGLContextLost = function() {
|
||||
clear(this.bufferCache_);
|
||||
clear(this.shaderCache_);
|
||||
clear(this.programCache_);
|
||||
this.currentProgram_ = null;
|
||||
this.hitDetectionFramebuffer_ = null;
|
||||
this.hitDetectionTexture_ = null;
|
||||
this.hitDetectionRenderbuffer_ = null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* FIXME empty description for jsdoc
|
||||
*/
|
||||
WebGLContext.prototype.handleWebGLContextRestored = function() {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a 1x1 pixel framebuffer for the hit-detection.
|
||||
* @private
|
||||
*/
|
||||
WebGLContext.prototype.initHitDetectionFramebuffer_ = function() {
|
||||
const gl = this.gl_;
|
||||
const framebuffer = gl.createFramebuffer();
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
|
||||
|
||||
const texture = createEmptyTexture(gl, 1, 1);
|
||||
const renderbuffer = gl.createRenderbuffer();
|
||||
gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer);
|
||||
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, 1, 1);
|
||||
gl.framebufferTexture2D(
|
||||
gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
|
||||
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT,
|
||||
gl.RENDERBUFFER, renderbuffer);
|
||||
|
||||
gl.bindTexture(gl.TEXTURE_2D, null);
|
||||
gl.bindRenderbuffer(gl.RENDERBUFFER, null);
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
||||
|
||||
this.hitDetectionFramebuffer_ = framebuffer;
|
||||
this.hitDetectionTexture_ = texture;
|
||||
this.hitDetectionRenderbuffer_ = renderbuffer;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Use a program. If the program is already in use, this will return `false`.
|
||||
* @param {WebGLProgram} program Program.
|
||||
* @return {boolean} Changed.
|
||||
* @api
|
||||
*/
|
||||
WebGLContext.prototype.useProgram = function(program) {
|
||||
if (program == this.currentProgram_) {
|
||||
return false;
|
||||
} else {
|
||||
const gl = this.getGL();
|
||||
gl.useProgram(program);
|
||||
this.currentProgram_ = program;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {WebGLRenderingContext} gl WebGL rendering context.
|
||||
* @param {number=} opt_wrapS wrapS.
|
||||
|
||||
@@ -11,17 +11,20 @@ import WebGLShader from '../webgl/Shader.js';
|
||||
* @param {string} source Source.
|
||||
* @struct
|
||||
*/
|
||||
const WebGLFragment = function(source) {
|
||||
WebGLShader.call(this, source);
|
||||
};
|
||||
class WebGLFragment {
|
||||
constructor(source) {
|
||||
WebGLShader.call(this, source);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
getType() {
|
||||
return FRAGMENT_SHADER;
|
||||
}
|
||||
}
|
||||
|
||||
inherits(WebGLFragment, WebGLShader);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
WebGLFragment.prototype.getType = function() {
|
||||
return FRAGMENT_SHADER;
|
||||
};
|
||||
export default WebGLFragment;
|
||||
|
||||
@@ -9,30 +9,30 @@ import {FALSE} from '../functions.js';
|
||||
* @param {string} source Source.
|
||||
* @struct
|
||||
*/
|
||||
const WebGLShader = function(source) {
|
||||
class WebGLShader {
|
||||
constructor(source) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {string}
|
||||
*/
|
||||
this.source_ = source;
|
||||
/**
|
||||
* @private
|
||||
* @type {string}
|
||||
*/
|
||||
this.source_ = source;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @abstract
|
||||
* @return {number} Type.
|
||||
*/
|
||||
getType() {}
|
||||
|
||||
/**
|
||||
* @abstract
|
||||
* @return {number} Type.
|
||||
*/
|
||||
WebGLShader.prototype.getType = function() {};
|
||||
|
||||
|
||||
/**
|
||||
* @return {string} Source.
|
||||
*/
|
||||
WebGLShader.prototype.getSource = function() {
|
||||
return this.source_;
|
||||
};
|
||||
/**
|
||||
* @return {string} Source.
|
||||
*/
|
||||
getSource() {
|
||||
return this.source_;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -11,17 +11,20 @@ import WebGLShader from '../webgl/Shader.js';
|
||||
* @param {string} source Source.
|
||||
* @struct
|
||||
*/
|
||||
const WebGLVertex = function(source) {
|
||||
WebGLShader.call(this, source);
|
||||
};
|
||||
class WebGLVertex {
|
||||
constructor(source) {
|
||||
WebGLShader.call(this, source);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
getType() {
|
||||
return VERTEX_SHADER;
|
||||
}
|
||||
}
|
||||
|
||||
inherits(WebGLVertex, WebGLShader);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
WebGLVertex.prototype.getType = function() {
|
||||
return VERTEX_SHADER;
|
||||
};
|
||||
export default WebGLVertex;
|
||||
|
||||
@@ -12,23 +12,28 @@ import {DEBUG as DEBUG_WEBGL} from '../../../../webgl.js';
|
||||
* @param {WebGLProgram} program Program.
|
||||
* @struct
|
||||
*/
|
||||
const Locations = function(gl, program) {
|
||||
{{#uniforms}}
|
||||
class Locations {
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.{{originalName}} = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? '{{originalName}}' : '{{shortName}}');
|
||||
{{/uniforms}}
|
||||
{{#attributes}}
|
||||
constructor(gl, program) {
|
||||
{{#uniforms}}
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.{{originalName}} = gl.getAttribLocation(
|
||||
program, DEBUG_WEBGL ? '{{originalName}}' : '{{shortName}}');
|
||||
{{/attributes}}
|
||||
};
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.{{originalName}} = gl.getUniformLocation(
|
||||
program, DEBUG_WEBGL ? '{{originalName}}' : '{{shortName}}');
|
||||
{{/uniforms}}
|
||||
{{#attributes}}
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.{{originalName}} = gl.getAttribLocation(
|
||||
program, DEBUG_WEBGL ? '{{originalName}}' : '{{shortName}}');
|
||||
{{/attributes}}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Locations;
|
||||
|
||||
Reference in New Issue
Block a user