Merge pull request #3214 from tschaub/raster
Pixel manipulation with raster sources.
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
goog.provide('ol.ImageCanvas');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('ol.ImageBase');
|
||||
goog.require('ol.ImageState');
|
||||
|
||||
@@ -13,12 +14,23 @@ goog.require('ol.ImageState');
|
||||
* @param {number} pixelRatio Pixel ratio.
|
||||
* @param {Array.<ol.Attribution>} attributions Attributions.
|
||||
* @param {HTMLCanvasElement} canvas Canvas.
|
||||
* @param {ol.ImageCanvasLoader=} opt_loader Optional loader function to
|
||||
* support asynchronous canvas drawing.
|
||||
*/
|
||||
ol.ImageCanvas = function(extent, resolution, pixelRatio, attributions,
|
||||
canvas) {
|
||||
canvas, opt_loader) {
|
||||
|
||||
goog.base(this, extent, resolution, pixelRatio, ol.ImageState.LOADED,
|
||||
attributions);
|
||||
/**
|
||||
* Optional canvas loader function.
|
||||
* @type {?ol.ImageCanvasLoader}
|
||||
* @private
|
||||
*/
|
||||
this.loader_ = goog.isDef(opt_loader) ? opt_loader : null;
|
||||
|
||||
var state = goog.isDef(opt_loader) ?
|
||||
ol.ImageState.IDLE : ol.ImageState.LOADED;
|
||||
|
||||
goog.base(this, extent, resolution, pixelRatio, state, attributions);
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -26,13 +38,68 @@ ol.ImageCanvas = function(extent, resolution, pixelRatio, attributions,
|
||||
*/
|
||||
this.canvas_ = canvas;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Error}
|
||||
*/
|
||||
this.error_ = null;
|
||||
|
||||
};
|
||||
goog.inherits(ol.ImageCanvas, ol.ImageBase);
|
||||
|
||||
|
||||
/**
|
||||
* Get any error associated with asynchronous rendering.
|
||||
* @return {Error} Any error that occurred during rendering.
|
||||
*/
|
||||
ol.ImageCanvas.prototype.getError = function() {
|
||||
return this.error_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handle async drawing complete.
|
||||
* @param {Error} err Any error during drawing.
|
||||
* @private
|
||||
*/
|
||||
ol.ImageCanvas.prototype.handleLoad_ = function(err) {
|
||||
if (err) {
|
||||
this.error_ = err;
|
||||
this.state = ol.ImageState.ERROR;
|
||||
} else {
|
||||
this.state = ol.ImageState.LOADED;
|
||||
}
|
||||
this.changed();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Trigger drawing on canvas.
|
||||
*/
|
||||
ol.ImageCanvas.prototype.load = function() {
|
||||
if (this.state == ol.ImageState.IDLE) {
|
||||
goog.asserts.assert(!goog.isNull(this.loader_));
|
||||
this.state = ol.ImageState.LOADING;
|
||||
this.changed();
|
||||
this.loader_(goog.bind(this.handleLoad_, this));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.ImageCanvas.prototype.getImage = function(opt_context) {
|
||||
return this.canvas_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A function that is called to trigger asynchronous canvas drawing. It is
|
||||
* called with a "done" callback that should be called when drawing is done.
|
||||
* If any error occurs during drawing, the "done" callback should be called with
|
||||
* that error.
|
||||
*
|
||||
* @typedef {function(function(Error))}
|
||||
*/
|
||||
ol.ImageCanvasLoader;
|
||||
|
||||
32
src/ol/raster/operation.js
Normal file
32
src/ol/raster/operation.js
Normal file
@@ -0,0 +1,32 @@
|
||||
goog.provide('ol.raster.Operation');
|
||||
goog.provide('ol.raster.OperationType');
|
||||
|
||||
|
||||
/**
|
||||
* Raster operation type. Supported values are `'pixel'` and `'image'`.
|
||||
* @enum {string}
|
||||
* @api
|
||||
*/
|
||||
ol.raster.OperationType = {
|
||||
PIXEL: 'pixel',
|
||||
IMAGE: 'image'
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A function that takes an array of input data, performs some operation, and
|
||||
* returns an array of ouput data. For `'pixel'` type operations, functions
|
||||
* will be called with an array of {@link ol.raster.Pixel} data and should
|
||||
* return an array of the same. For `'image'` type operations, functions will
|
||||
* be called with an array of {@link ImageData
|
||||
* https://developer.mozilla.org/en-US/docs/Web/API/ImageData} and should return
|
||||
* an array of the same. The operations are called with a second "data"
|
||||
* argument, which can be used for storage. The data object is accessible
|
||||
* from raster events, where it can be initialized in "beforeoperations" and
|
||||
* accessed again in "afteroperations".
|
||||
*
|
||||
* @typedef {function((Array.<ol.raster.Pixel>|Array.<ImageData>), Object):
|
||||
* (Array.<ol.raster.Pixel>|Array.<ImageData>)}
|
||||
* @api
|
||||
*/
|
||||
ol.raster.Operation;
|
||||
9
src/ol/raster/pixel.js
Normal file
9
src/ol/raster/pixel.js
Normal file
@@ -0,0 +1,9 @@
|
||||
goog.provide('ol.raster.Pixel');
|
||||
|
||||
|
||||
/**
|
||||
* An array of numbers representing pixel values.
|
||||
* @typedef {Array.<number>} ol.raster.Pixel
|
||||
* @api
|
||||
*/
|
||||
ol.raster.Pixel;
|
||||
@@ -113,7 +113,6 @@ ol.renderer.Layer.prototype.createLoadedTileFinder = function(source, tiles) {
|
||||
|
||||
|
||||
/**
|
||||
* @protected
|
||||
* @return {ol.layer.Layer} Layer.
|
||||
*/
|
||||
ol.renderer.Layer.prototype.getLayer = function() {
|
||||
|
||||
535
src/ol/source/rastersource.js
Normal file
535
src/ol/source/rastersource.js
Normal file
@@ -0,0 +1,535 @@
|
||||
goog.provide('ol.source.Raster');
|
||||
goog.provide('ol.source.RasterEvent');
|
||||
goog.provide('ol.source.RasterEventType');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.events');
|
||||
goog.require('goog.events.Event');
|
||||
goog.require('goog.events.EventType');
|
||||
goog.require('goog.functions');
|
||||
goog.require('goog.object');
|
||||
goog.require('goog.vec.Mat4');
|
||||
goog.require('ol.ImageCanvas');
|
||||
goog.require('ol.TileQueue');
|
||||
goog.require('ol.dom');
|
||||
goog.require('ol.ext.pixelworks');
|
||||
goog.require('ol.extent');
|
||||
goog.require('ol.layer.Image');
|
||||
goog.require('ol.layer.Tile');
|
||||
goog.require('ol.raster.OperationType');
|
||||
goog.require('ol.renderer.canvas.ImageLayer');
|
||||
goog.require('ol.renderer.canvas.TileLayer');
|
||||
goog.require('ol.source.Image');
|
||||
goog.require('ol.source.State');
|
||||
goog.require('ol.source.Tile');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* A source that transforms data from any number of input sources using an array
|
||||
* of {@link ol.raster.Operation} functions to transform input pixel values into
|
||||
* output pixel values.
|
||||
*
|
||||
* @constructor
|
||||
* @extends {ol.source.Image}
|
||||
* @param {olx.source.RasterOptions} options Options.
|
||||
* @api
|
||||
*/
|
||||
ol.source.Raster = function(options) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {*}
|
||||
*/
|
||||
this.worker_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.raster.OperationType}
|
||||
*/
|
||||
this.operationType_ = goog.isDef(options.operationType) ?
|
||||
options.operationType : ol.raster.OperationType.PIXEL;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.threads_ = goog.isDef(options.threads) ? options.threads : 1;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<ol.renderer.canvas.Layer>}
|
||||
*/
|
||||
this.renderers_ = ol.source.Raster.createRenderers_(options.sources);
|
||||
|
||||
for (var r = 0, rr = this.renderers_.length; r < rr; ++r) {
|
||||
goog.events.listen(this.renderers_[r], goog.events.EventType.CHANGE,
|
||||
this.changed, false, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {CanvasRenderingContext2D}
|
||||
*/
|
||||
this.canvasContext_ = ol.dom.createCanvasContext2D();
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.TileQueue}
|
||||
*/
|
||||
this.tileQueue_ = new ol.TileQueue(
|
||||
goog.functions.constant(1),
|
||||
goog.bind(this.changed, this));
|
||||
|
||||
var layerStatesArray = ol.source.Raster.getLayerStatesArray_(this.renderers_);
|
||||
var layerStates = {};
|
||||
for (var i = 0, ii = layerStatesArray.length; i < ii; ++i) {
|
||||
layerStates[goog.getUid(layerStatesArray[i].layer)] = layerStatesArray[i];
|
||||
}
|
||||
|
||||
/**
|
||||
* The most recently rendered state.
|
||||
* @type {?ol.source.Raster.RenderedState}
|
||||
* @private
|
||||
*/
|
||||
this.renderedState_ = null;
|
||||
|
||||
/**
|
||||
* The most recently rendered image canvas.
|
||||
* @type {ol.ImageCanvas}
|
||||
* @private
|
||||
*/
|
||||
this.renderedImageCanvas_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {olx.FrameState}
|
||||
*/
|
||||
this.frameState_ = {
|
||||
animate: false,
|
||||
attributions: {},
|
||||
coordinateToPixelMatrix: goog.vec.Mat4.createNumber(),
|
||||
extent: null,
|
||||
focus: null,
|
||||
index: 0,
|
||||
layerStates: layerStates,
|
||||
layerStatesArray: layerStatesArray,
|
||||
logos: {},
|
||||
pixelRatio: 1,
|
||||
pixelToCoordinateMatrix: goog.vec.Mat4.createNumber(),
|
||||
postRenderFunctions: [],
|
||||
size: [0, 0],
|
||||
skippedFeatureUids: {},
|
||||
tileQueue: this.tileQueue_,
|
||||
time: Date.now(),
|
||||
usedTiles: {},
|
||||
viewState: /** @type {olx.ViewState} */ ({
|
||||
rotation: 0
|
||||
}),
|
||||
viewHints: [],
|
||||
wantedTiles: {}
|
||||
};
|
||||
|
||||
goog.base(this, {});
|
||||
|
||||
if (goog.isDef(options.operation)) {
|
||||
this.setOperation(options.operation, options.lib);
|
||||
}
|
||||
|
||||
};
|
||||
goog.inherits(ol.source.Raster, ol.source.Image);
|
||||
|
||||
|
||||
/**
|
||||
* Set the operation.
|
||||
* @param {ol.raster.Operation} operation New operation.
|
||||
* @param {Object=} opt_lib Functions that will be available to operations run
|
||||
* in a worker.
|
||||
* @api
|
||||
*/
|
||||
ol.source.Raster.prototype.setOperation = function(operation, opt_lib) {
|
||||
this.worker_ = new ol.ext.pixelworks.Processor({
|
||||
operation: operation,
|
||||
imageOps: this.operationType_ === ol.raster.OperationType.IMAGE,
|
||||
queue: 1,
|
||||
lib: opt_lib,
|
||||
threads: this.threads_
|
||||
});
|
||||
this.changed();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Update the stored frame state.
|
||||
* @param {ol.Extent} extent The view extent (in map units).
|
||||
* @param {number} resolution The view resolution.
|
||||
* @param {ol.proj.Projection} projection The view projection.
|
||||
* @return {olx.FrameState} The updated frame state.
|
||||
* @private
|
||||
*/
|
||||
ol.source.Raster.prototype.updateFrameState_ =
|
||||
function(extent, resolution, projection) {
|
||||
|
||||
var frameState = /** @type {olx.FrameState} */ (
|
||||
goog.object.clone(this.frameState_));
|
||||
|
||||
frameState.viewState = /** @type {olx.ViewState} */ (
|
||||
goog.object.clone(frameState.viewState));
|
||||
|
||||
var center = ol.extent.getCenter(extent);
|
||||
var width = Math.round(ol.extent.getWidth(extent) / resolution);
|
||||
var height = Math.round(ol.extent.getHeight(extent) / resolution);
|
||||
|
||||
frameState.extent = extent;
|
||||
frameState.focus = ol.extent.getCenter(extent);
|
||||
frameState.size[0] = width;
|
||||
frameState.size[1] = height;
|
||||
|
||||
var viewState = frameState.viewState;
|
||||
viewState.center = center;
|
||||
viewState.projection = projection;
|
||||
viewState.resolution = resolution;
|
||||
return frameState;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Determine if the most recently rendered image canvas is dirty.
|
||||
* @param {ol.Extent} extent The requested extent.
|
||||
* @param {number} resolution The requested resolution.
|
||||
* @return {boolean} The image is dirty.
|
||||
* @private
|
||||
*/
|
||||
ol.source.Raster.prototype.isDirty_ = function(extent, resolution) {
|
||||
var state = this.renderedState_;
|
||||
return !state ||
|
||||
this.getRevision() !== state.revision ||
|
||||
resolution !== state.resolution ||
|
||||
!ol.extent.equals(extent, state.extent);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.source.Raster.prototype.getImage =
|
||||
function(extent, resolution, pixelRatio, projection) {
|
||||
|
||||
if (!this.allSourcesReady_()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!this.isDirty_(extent, resolution)) {
|
||||
return this.renderedImageCanvas_;
|
||||
}
|
||||
|
||||
var context = this.canvasContext_;
|
||||
var canvas = context.canvas;
|
||||
|
||||
var width = Math.round(ol.extent.getWidth(extent) / resolution);
|
||||
var height = Math.round(ol.extent.getHeight(extent) / resolution);
|
||||
|
||||
if (width !== canvas.width ||
|
||||
height !== canvas.height) {
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
}
|
||||
|
||||
var frameState = this.updateFrameState_(extent, resolution, projection);
|
||||
|
||||
var imageCanvas = new ol.ImageCanvas(
|
||||
extent, resolution, 1, this.getAttributions(), canvas,
|
||||
this.composeFrame_.bind(this, frameState));
|
||||
|
||||
this.renderedImageCanvas_ = imageCanvas;
|
||||
|
||||
this.renderedState_ = {
|
||||
extent: extent,
|
||||
resolution: resolution,
|
||||
revision: this.getRevision()
|
||||
};
|
||||
|
||||
return imageCanvas;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Determine if all sources are ready.
|
||||
* @return {boolean} All sources are ready.
|
||||
* @private
|
||||
*/
|
||||
ol.source.Raster.prototype.allSourcesReady_ = function() {
|
||||
var ready = true;
|
||||
var source;
|
||||
for (var i = 0, ii = this.renderers_.length; i < ii; ++i) {
|
||||
source = this.renderers_[i].getLayer().getSource();
|
||||
if (source.getState() !== ol.source.State.READY) {
|
||||
ready = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ready;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Compose the frame. This renders data from all sources, runs pixel-wise
|
||||
* operations, and renders the result to the stored canvas context.
|
||||
* @param {olx.FrameState} frameState The frame state.
|
||||
* @param {function(Error)} callback Called when composition is complete.
|
||||
* @private
|
||||
*/
|
||||
ol.source.Raster.prototype.composeFrame_ = function(frameState, callback) {
|
||||
var len = this.renderers_.length;
|
||||
var imageDatas = new Array(len);
|
||||
for (var i = 0; i < len; ++i) {
|
||||
var imageData = ol.source.Raster.getImageData_(
|
||||
this.renderers_[i], frameState, frameState.layerStatesArray[i]);
|
||||
if (imageData) {
|
||||
imageDatas[i] = imageData;
|
||||
} else {
|
||||
// image not yet ready
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var data = {};
|
||||
this.dispatchEvent(new ol.source.RasterEvent(
|
||||
ol.source.RasterEventType.BEFOREOPERATIONS, frameState, data));
|
||||
|
||||
this.worker_.process(imageDatas, data,
|
||||
this.onWorkerComplete_.bind(this, frameState, callback));
|
||||
|
||||
frameState.tileQueue.loadMoreTiles(16, 16);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Called when pixel processing is complete.
|
||||
* @param {olx.FrameState} frameState The frame state.
|
||||
* @param {function(Error)} callback Called when rendering is complete.
|
||||
* @param {Error} err Any error during processing.
|
||||
* @param {ImageData} output The output image data.
|
||||
* @param {Object} data The user data.
|
||||
* @private
|
||||
*/
|
||||
ol.source.Raster.prototype.onWorkerComplete_ =
|
||||
function(frameState, callback, err, output, data) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
if (goog.isNull(output)) {
|
||||
// job aborted
|
||||
return;
|
||||
}
|
||||
|
||||
this.dispatchEvent(new ol.source.RasterEvent(
|
||||
ol.source.RasterEventType.AFTEROPERATIONS, frameState, data));
|
||||
|
||||
var resolution = frameState.viewState.resolution / frameState.pixelRatio;
|
||||
if (!this.isDirty_(frameState.extent, resolution)) {
|
||||
this.canvasContext_.putImageData(output, 0, 0);
|
||||
}
|
||||
|
||||
callback(null);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get image data from a renderer.
|
||||
* @param {ol.renderer.canvas.Layer} renderer Layer renderer.
|
||||
* @param {olx.FrameState} frameState The frame state.
|
||||
* @param {ol.layer.LayerState} layerState The layer state.
|
||||
* @return {ImageData} The image data.
|
||||
* @private
|
||||
*/
|
||||
ol.source.Raster.getImageData_ = function(renderer, frameState, layerState) {
|
||||
renderer.prepareFrame(frameState, layerState);
|
||||
// We should be able to call renderer.composeFrame(), but this is inefficient
|
||||
// for tiled sources (we've already rendered to an intermediate canvas in the
|
||||
// prepareFrame call and we don't need to render again to the output canvas).
|
||||
// TODO: make all canvas renderers render to a single canvas
|
||||
var image = renderer.getImage();
|
||||
if (!image) {
|
||||
return null;
|
||||
}
|
||||
var imageTransform = renderer.getImageTransform();
|
||||
var dx = Math.round(goog.vec.Mat4.getElement(imageTransform, 0, 3));
|
||||
var dy = Math.round(goog.vec.Mat4.getElement(imageTransform, 1, 3));
|
||||
var width = frameState.size[0];
|
||||
var height = frameState.size[1];
|
||||
if (image instanceof Image) {
|
||||
if (!ol.source.Raster.context_) {
|
||||
ol.source.Raster.context_ = ol.dom.createCanvasContext2D(width, height);
|
||||
} else {
|
||||
var canvas = ol.source.Raster.context_.canvas;
|
||||
if (canvas.width !== width || canvas.height !== height) {
|
||||
ol.source.Raster.context_ = ol.dom.createCanvasContext2D(width, height);
|
||||
} else {
|
||||
ol.source.Raster.context_.clearRect(0, 0, width, height);
|
||||
}
|
||||
}
|
||||
var dw = Math.round(
|
||||
image.width * goog.vec.Mat4.getElement(imageTransform, 0, 0));
|
||||
var dh = Math.round(
|
||||
image.height * goog.vec.Mat4.getElement(imageTransform, 1, 1));
|
||||
ol.source.Raster.context_.drawImage(image, dx, dy, dw, dh);
|
||||
return ol.source.Raster.context_.getImageData(0, 0, width, height);
|
||||
} else {
|
||||
return image.getContext('2d').getImageData(-dx, -dy, width, height);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A reusable canvas context.
|
||||
* @type {CanvasRenderingContext2D}
|
||||
* @private
|
||||
*/
|
||||
ol.source.Raster.context_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* Get a list of layer states from a list of renderers.
|
||||
* @param {Array.<ol.renderer.canvas.Layer>} renderers Layer renderers.
|
||||
* @return {Array.<ol.layer.LayerState>} The layer states.
|
||||
* @private
|
||||
*/
|
||||
ol.source.Raster.getLayerStatesArray_ = function(renderers) {
|
||||
return renderers.map(function(renderer) {
|
||||
return renderer.getLayer().getLayerState();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Create renderers for all sources.
|
||||
* @param {Array.<ol.source.Source>} sources The sources.
|
||||
* @return {Array.<ol.renderer.canvas.Layer>} Array of layer renderers.
|
||||
* @private
|
||||
*/
|
||||
ol.source.Raster.createRenderers_ = function(sources) {
|
||||
var len = sources.length;
|
||||
var renderers = new Array(len);
|
||||
for (var i = 0; i < len; ++i) {
|
||||
renderers[i] = ol.source.Raster.createRenderer_(sources[i]);
|
||||
}
|
||||
return renderers;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Create a renderer for the provided source.
|
||||
* @param {ol.source.Source} source The source.
|
||||
* @return {ol.renderer.canvas.Layer} The renderer.
|
||||
* @private
|
||||
*/
|
||||
ol.source.Raster.createRenderer_ = function(source) {
|
||||
var renderer = null;
|
||||
if (source instanceof ol.source.Tile) {
|
||||
renderer = ol.source.Raster.createTileRenderer_(
|
||||
/** @type {ol.source.Tile} */ (source));
|
||||
} else if (source instanceof ol.source.Image) {
|
||||
renderer = ol.source.Raster.createImageRenderer_(
|
||||
/** @type {ol.source.Image} */ (source));
|
||||
} else {
|
||||
goog.asserts.fail('Unsupported source type: ' + source);
|
||||
}
|
||||
return renderer;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Create an image renderer for the provided source.
|
||||
* @param {ol.source.Image} source The source.
|
||||
* @return {ol.renderer.canvas.Layer} The renderer.
|
||||
* @private
|
||||
*/
|
||||
ol.source.Raster.createImageRenderer_ = function(source) {
|
||||
var layer = new ol.layer.Image({source: source});
|
||||
return new ol.renderer.canvas.ImageLayer(layer);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Create a tile renderer for the provided source.
|
||||
* @param {ol.source.Tile} source The source.
|
||||
* @return {ol.renderer.canvas.Layer} The renderer.
|
||||
* @private
|
||||
*/
|
||||
ol.source.Raster.createTileRenderer_ = function(source) {
|
||||
var layer = new ol.layer.Tile({source: source});
|
||||
return new ol.renderer.canvas.TileLayer(layer);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {{revision: number,
|
||||
* resolution: number,
|
||||
* extent: ol.Extent}}
|
||||
*/
|
||||
ol.source.Raster.RenderedState;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Events emitted by {@link ol.source.Raster} instances are instances of this
|
||||
* type.
|
||||
*
|
||||
* @constructor
|
||||
* @extends {goog.events.Event}
|
||||
* @implements {oli.source.RasterEvent}
|
||||
* @param {string} type Type.
|
||||
* @param {olx.FrameState} frameState The frame state.
|
||||
* @param {Object} data An object made available to operations.
|
||||
*/
|
||||
ol.source.RasterEvent = function(type, frameState, data) {
|
||||
goog.base(this, type);
|
||||
|
||||
/**
|
||||
* The raster extent.
|
||||
* @type {ol.Extent}
|
||||
* @api
|
||||
*/
|
||||
this.extent = frameState.extent;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
};
|
||||
goog.inherits(ol.source.RasterEvent, goog.events.Event);
|
||||
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
*/
|
||||
ol.source.RasterEventType = {
|
||||
/**
|
||||
* Triggered before operations are run.
|
||||
* @event ol.source.RasterEvent#beforeoperations
|
||||
* @api
|
||||
*/
|
||||
BEFOREOPERATIONS: 'beforeoperations',
|
||||
|
||||
/**
|
||||
* Triggered after operations are run.
|
||||
* @event ol.source.RasterEvent#afteroperations
|
||||
* @api
|
||||
*/
|
||||
AFTEROPERATIONS: 'afteroperations'
|
||||
};
|
||||
Reference in New Issue
Block a user