diff --git a/examples/raster.js b/examples/raster.js
index 37ea3d5596..e62c55b208 100644
--- a/examples/raster.js
+++ b/examples/raster.js
@@ -7,7 +7,7 @@ goog.require('ol.layer.Tile');
goog.require('ol.source.BingMaps');
goog.require('ol.source.Raster');
-function tgi(pixels) {
+function tgi(pixels, data) {
var pixel = pixels[0];
var r = pixel[0] / 255;
var g = pixel[1] / 255;
@@ -17,20 +17,17 @@ function tgi(pixels) {
return pixels;
}
-var counts = new Counts(0, 25);
-function summarize(pixels) {
+function summarize(pixels, data) {
var value = pixels[0][0];
- counts.increment(value);
+ data.counts.increment(value);
return pixels;
}
-var threshold = 10;
-
-function color(pixels) {
+function color(pixels, data) {
var pixel = pixels[0];
var value = pixel[0];
- if (value > threshold) {
+ if (value > data.threshold) {
pixel[0] = 0;
pixel[1] = 255;
pixel[2] = 0;
@@ -51,12 +48,17 @@ var raster = new ol.source.Raster({
operations: [tgi, summarize, color]
});
-raster.on('beforeoperations', function() {
+var counts = new Counts(0, 25);
+var threshold = 10;
+
+raster.on('beforeoperations', function(event) {
counts.clear();
+ event.data.counts = counts;
+ event.data.threshold = threshold;
});
raster.on('afteroperations', function(event) {
- schedulePlot(event.resolution);
+ schedulePlot(event.resolution, event.data.counts);
});
var map = new ol.Map({
@@ -114,12 +116,12 @@ Counts.prototype.increment = function(value) {
};
var timer = null;
-function schedulePlot(resolution) {
+function schedulePlot(resolution, counts) {
if (timer) {
clearTimeout(timer);
timer = null;
}
- timer = setTimeout(plot.bind(null, resolution), 1000 / 60);
+ timer = setTimeout(plot.bind(null, resolution, counts), 1000 / 60);
}
var barWidth = 15;
@@ -133,7 +135,7 @@ var chartRect = chart[0][0].getBoundingClientRect();
var tip = d3.select(document.body).append('div')
.attr('class', 'tip');
-function plot(resolution) {
+function plot(resolution, counts) {
var yScale = d3.scale.linear()
.domain([0, d3.max(counts.values)])
.range([0, plotHeight]);
diff --git a/externs/oli.js b/externs/oli.js
index 56b8afb229..7d1631024d 100644
--- a/externs/oli.js
+++ b/externs/oli.js
@@ -284,6 +284,12 @@ oli.source.RasterEvent.prototype.extent;
oli.source.RasterEvent.prototype.resolution;
+/**
+ * @type {Object}
+ */
+oli.source.RasterEvent.prototype.data;
+
+
/**
* @interface
*/
diff --git a/src/ol/raster/operation.js b/src/ol/raster/operation.js
index b88d99c8af..340bc37ff7 100644
--- a/src/ol/raster/operation.js
+++ b/src/ol/raster/operation.js
@@ -21,9 +21,12 @@ ol.raster.OperationType = {
* 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.
+ * 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.
|Array.)):
+ * @typedef {function((Array.|Array.), Object):
* (Array.|Array.)}
* @api
*/
diff --git a/src/ol/source/rastersource.js b/src/ol/source/rastersource.js
index cc51c561b4..09bc5f28f3 100644
--- a/src/ol/source/rastersource.js
+++ b/src/ol/source/rastersource.js
@@ -223,8 +223,9 @@ ol.source.Raster.prototype.composeFrame_ = function(frameState) {
this.renderers_[i], frameState, frameState.layerStatesArray[i]);
}
+ var data = {};
this.dispatchEvent(new ol.source.RasterEvent(
- ol.source.RasterEventType.BEFOREOPERATIONS, frameState));
+ ol.source.RasterEventType.BEFOREOPERATIONS, frameState, data));
var targetImageData = null;
if (this.operationType_ === ol.raster.OperationType.PIXEL) {
@@ -242,20 +243,20 @@ ol.source.Raster.prototype.composeFrame_ = function(frameState) {
pixel[2] = source[j + 2];
pixel[3] = source[j + 3];
}
- pixel = this.runPixelOperations_(pixels)[0];
+ pixel = this.runPixelOperations_(pixels, data)[0];
target[j] = pixel[0];
target[j + 1] = pixel[1];
target[j + 2] = pixel[2];
target[j + 3] = pixel[3];
}
} else if (this.operationType_ === ol.raster.OperationType.IMAGE) {
- targetImageData = this.runImageOperations_(imageDatas)[0];
+ targetImageData = this.runImageOperations_(imageDatas, data)[0];
} else {
goog.asserts.fail('unsupported operation type: ' + this.operationType_);
}
this.dispatchEvent(new ol.source.RasterEvent(
- ol.source.RasterEventType.AFTEROPERATIONS, frameState));
+ ol.source.RasterEventType.AFTEROPERATIONS, frameState, data));
context.putImageData(targetImageData, 0, 0);
@@ -266,12 +267,13 @@ ol.source.Raster.prototype.composeFrame_ = function(frameState) {
/**
* Run pixel-wise operations to transform pixels.
* @param {Array.} pixels The input pixels.
+ * @param {Object} data User storage.
* @return {Array.} The modified pixels.
* @private
*/
-ol.source.Raster.prototype.runPixelOperations_ = function(pixels) {
+ol.source.Raster.prototype.runPixelOperations_ = function(pixels, data) {
for (var i = 0, ii = this.operations_.length; i < ii; ++i) {
- pixels = this.operations_[i](pixels);
+ pixels = this.operations_[i](pixels, data);
}
return pixels;
};
@@ -280,12 +282,13 @@ ol.source.Raster.prototype.runPixelOperations_ = function(pixels) {
/**
* Run image operations.
* @param {Array.} imageDatas The input image data.
+ * @param {Object} data User storage.
* @return {Array.} The output image data.
* @private
*/
-ol.source.Raster.prototype.runImageOperations_ = function(imageDatas) {
+ol.source.Raster.prototype.runImageOperations_ = function(imageDatas, data) {
for (var i = 0, ii = this.operations_.length; i < ii; ++i) {
- imageDatas = this.operations_[i](imageDatas);
+ imageDatas = this.operations_[i](imageDatas, data);
}
return imageDatas;
};
@@ -396,8 +399,9 @@ ol.source.Raster.createTileRenderer_ = function(source) {
* @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) {
+ol.source.RasterEvent = function(type, frameState, data) {
goog.base(this, type);
/**
@@ -414,6 +418,14 @@ ol.source.RasterEvent = function(type, frameState) {
*/
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);