Merge pull request #6222 from ahocevar/fix-foreachlayeratpixel
Fix forEachLayerAtPixel and improve class hierarchy
This commit is contained in:
@@ -2,23 +2,20 @@ goog.provide('ol.renderer.canvas.ImageLayer');
|
|||||||
|
|
||||||
goog.require('ol');
|
goog.require('ol');
|
||||||
goog.require('ol.View');
|
goog.require('ol.View');
|
||||||
goog.require('ol.dom');
|
|
||||||
goog.require('ol.extent');
|
goog.require('ol.extent');
|
||||||
goog.require('ol.functions');
|
|
||||||
goog.require('ol.proj');
|
goog.require('ol.proj');
|
||||||
goog.require('ol.renderer.canvas.Layer');
|
goog.require('ol.renderer.canvas.IntermediateCanvas');
|
||||||
goog.require('ol.source.ImageVector');
|
|
||||||
goog.require('ol.transform');
|
goog.require('ol.transform');
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constructor
|
* @constructor
|
||||||
* @extends {ol.renderer.canvas.Layer}
|
* @extends {ol.renderer.canvas.IntermediateCanvas}
|
||||||
* @param {ol.layer.Image} imageLayer Single image layer.
|
* @param {ol.layer.Image} imageLayer Single image layer.
|
||||||
*/
|
*/
|
||||||
ol.renderer.canvas.ImageLayer = function(imageLayer) {
|
ol.renderer.canvas.ImageLayer = function(imageLayer) {
|
||||||
|
|
||||||
ol.renderer.canvas.Layer.call(this, imageLayer);
|
ol.renderer.canvas.IntermediateCanvas.call(this, imageLayer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
@@ -32,88 +29,8 @@ ol.renderer.canvas.ImageLayer = function(imageLayer) {
|
|||||||
*/
|
*/
|
||||||
this.imageTransform_ = ol.transform.create();
|
this.imageTransform_ = ol.transform.create();
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {ol.Transform}
|
|
||||||
*/
|
|
||||||
this.coordinateToCanvasPixelTransform_ = ol.transform.create();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {CanvasRenderingContext2D}
|
|
||||||
*/
|
|
||||||
this.hitCanvasContext_ = null;
|
|
||||||
|
|
||||||
};
|
|
||||||
ol.inherits(ol.renderer.canvas.ImageLayer, ol.renderer.canvas.Layer);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
ol.renderer.canvas.ImageLayer.prototype.forEachFeatureAtCoordinate = function(coordinate, frameState, callback, thisArg) {
|
|
||||||
var layer = this.getLayer();
|
|
||||||
var source = layer.getSource();
|
|
||||||
var resolution = frameState.viewState.resolution;
|
|
||||||
var rotation = frameState.viewState.rotation;
|
|
||||||
var skippedFeatureUids = frameState.skippedFeatureUids;
|
|
||||||
return source.forEachFeatureAtCoordinate(
|
|
||||||
coordinate, resolution, rotation, skippedFeatureUids,
|
|
||||||
/**
|
|
||||||
* @param {ol.Feature|ol.render.Feature} feature Feature.
|
|
||||||
* @return {?} Callback result.
|
|
||||||
*/
|
|
||||||
function(feature) {
|
|
||||||
return callback.call(thisArg, feature, layer);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {ol.Coordinate} coordinate Coordinate.
|
|
||||||
* @param {olx.FrameState} frameState FrameState.
|
|
||||||
* @param {function(this: S, ol.layer.Layer, (Uint8ClampedArray|Uint8Array)): T} callback Layer
|
|
||||||
* callback.
|
|
||||||
* @param {S} thisArg Value to use as `this` when executing `callback`.
|
|
||||||
* @return {T|undefined} Callback result.
|
|
||||||
* @template S,T,U
|
|
||||||
*/
|
|
||||||
ol.renderer.canvas.ImageLayer.prototype.forEachLayerAtCoordinate = function(coordinate, frameState, callback, thisArg) {
|
|
||||||
if (!this.getImage()) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.getLayer().getSource() instanceof ol.source.ImageVector) {
|
|
||||||
// for ImageVector sources use the original hit-detection logic,
|
|
||||||
// so that for example also transparent polygons are detected
|
|
||||||
var hasFeature = this.forEachFeatureAtCoordinate(
|
|
||||||
coordinate, frameState, ol.functions.TRUE, this);
|
|
||||||
|
|
||||||
if (hasFeature) {
|
|
||||||
return callback.call(thisArg, this.getLayer(), null);
|
|
||||||
} else {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
var pixelOnCanvas = ol.transform.apply(
|
|
||||||
this.coordinateToCanvasPixelTransform_, coordinate.slice());
|
|
||||||
|
|
||||||
if (!this.hitCanvasContext_) {
|
|
||||||
this.hitCanvasContext_ = ol.dom.createCanvasContext2D(1, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.hitCanvasContext_.clearRect(0, 0, 1, 1);
|
|
||||||
this.hitCanvasContext_.drawImage(
|
|
||||||
this.getImage(), pixelOnCanvas[0], pixelOnCanvas[1], 1, 1, 0, 0, 1, 1);
|
|
||||||
|
|
||||||
var imageData = this.hitCanvasContext_.getImageData(0, 0, 1, 1).data;
|
|
||||||
if (imageData[3] > 0) {
|
|
||||||
return callback.call(thisArg, this.getLayer(), imageData);
|
|
||||||
} else {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
ol.inherits(ol.renderer.canvas.ImageLayer, ol.renderer.canvas.IntermediateCanvas);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -172,6 +89,7 @@ ol.renderer.canvas.ImageLayer.prototype.prepareFrame = function(frameState, laye
|
|||||||
var loaded = this.loadImage(image);
|
var loaded = this.loadImage(image);
|
||||||
if (loaded) {
|
if (loaded) {
|
||||||
this.image_ = image;
|
this.image_ = image;
|
||||||
|
this.renderedResolution = viewResolution;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -183,19 +101,18 @@ ol.renderer.canvas.ImageLayer.prototype.prepareFrame = function(frameState, laye
|
|||||||
var imagePixelRatio = image.getPixelRatio();
|
var imagePixelRatio = image.getPixelRatio();
|
||||||
var scale = pixelRatio * imageResolution /
|
var scale = pixelRatio * imageResolution /
|
||||||
(viewResolution * imagePixelRatio);
|
(viewResolution * imagePixelRatio);
|
||||||
var transform = ol.transform.reset(this.imageTransform_);
|
var transform = ol.transform.compose(this.imageTransform_,
|
||||||
ol.transform.translate(transform,
|
pixelRatio * size[0] / 2, pixelRatio * size[1] / 2,
|
||||||
pixelRatio * frameState.size[0] / 2,
|
scale, scale,
|
||||||
pixelRatio * frameState.size[1] / 2);
|
0,
|
||||||
ol.transform.scale(transform, scale, scale);
|
|
||||||
ol.transform.translate(transform,
|
|
||||||
imagePixelRatio * (imageExtent[0] - viewCenter[0]) / imageResolution,
|
imagePixelRatio * (imageExtent[0] - viewCenter[0]) / imageResolution,
|
||||||
imagePixelRatio * (viewCenter[1] - imageExtent[3]) / imageResolution);
|
imagePixelRatio * (viewCenter[1] - imageExtent[3]) / imageResolution);
|
||||||
ol.transform.compose(ol.transform.reset(this.coordinateToCanvasPixelTransform_),
|
ol.transform.compose(this.coordinateToCanvasPixelTransform,
|
||||||
pixelRatio * size[0] / 2 - transform[4], pixelRatio * size[1] / 2 - transform[5],
|
pixelRatio * size[0] / 2 - transform[4], pixelRatio * size[1] / 2 - transform[5],
|
||||||
pixelRatio / viewResolution, -pixelRatio / viewResolution,
|
pixelRatio / viewResolution, -pixelRatio / viewResolution,
|
||||||
0,
|
0,
|
||||||
-viewCenter[0], -viewCenter[1]);
|
-viewCenter[0], -viewCenter[1]);
|
||||||
|
|
||||||
this.updateAttributions(frameState.attributions, image.getAttributions());
|
this.updateAttributions(frameState.attributions, image.getAttributions());
|
||||||
this.updateLogos(frameState, imageSource);
|
this.updateLogos(frameState, imageSource);
|
||||||
}
|
}
|
||||||
|
|||||||
149
src/ol/renderer/canvas/intermediatecanvas.js
Normal file
149
src/ol/renderer/canvas/intermediatecanvas.js
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
goog.provide('ol.renderer.canvas.IntermediateCanvas');
|
||||||
|
|
||||||
|
goog.require('ol');
|
||||||
|
goog.require('ol.coordinate');
|
||||||
|
goog.require('ol.dom');
|
||||||
|
goog.require('ol.renderer.canvas.Layer');
|
||||||
|
goog.require('ol.transform');
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @extends {ol.renderer.canvas.Layer}
|
||||||
|
* @param {ol.layer.Layer} layer Layer.
|
||||||
|
*/
|
||||||
|
ol.renderer.canvas.IntermediateCanvas = function(layer) {
|
||||||
|
|
||||||
|
ol.renderer.canvas.Layer.call(this, layer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @protected
|
||||||
|
* @type {ol.Transform}
|
||||||
|
*/
|
||||||
|
this.coordinateToCanvasPixelTransform = ol.transform.create();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {CanvasRenderingContext2D}
|
||||||
|
*/
|
||||||
|
this.hitCanvasContext_ = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @protected
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
this.renderedResolution;
|
||||||
|
|
||||||
|
};
|
||||||
|
ol.inherits(ol.renderer.canvas.IntermediateCanvas, ol.renderer.canvas.Layer);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.renderer.canvas.IntermediateCanvas.prototype.composeFrame = function(frameState, layerState, context) {
|
||||||
|
|
||||||
|
this.preCompose(context, frameState);
|
||||||
|
|
||||||
|
var image = this.getImage();
|
||||||
|
if (image) {
|
||||||
|
|
||||||
|
// clipped rendering if layer extent is set
|
||||||
|
var extent = layerState.extent;
|
||||||
|
var clipped = extent !== undefined;
|
||||||
|
if (clipped) {
|
||||||
|
this.clip(context, frameState, /** @type {ol.Extent} */ (extent));
|
||||||
|
}
|
||||||
|
|
||||||
|
var imageTransform = this.getImageTransform();
|
||||||
|
// for performance reasons, context.save / context.restore is not used
|
||||||
|
// to save and restore the transformation matrix and the opacity.
|
||||||
|
// see http://jsperf.com/context-save-restore-versus-variable
|
||||||
|
var alpha = context.globalAlpha;
|
||||||
|
context.globalAlpha = layerState.opacity;
|
||||||
|
|
||||||
|
// for performance reasons, context.setTransform is only used
|
||||||
|
// when the view is rotated. see http://jsperf.com/canvas-transform
|
||||||
|
var dx = imageTransform[4];
|
||||||
|
var dy = imageTransform[5];
|
||||||
|
var dw = image.width * imageTransform[0];
|
||||||
|
var dh = image.height * imageTransform[3];
|
||||||
|
context.drawImage(image, 0, 0, +image.width, +image.height,
|
||||||
|
Math.round(dx), Math.round(dy), Math.round(dw), Math.round(dh));
|
||||||
|
context.globalAlpha = alpha;
|
||||||
|
|
||||||
|
if (clipped) {
|
||||||
|
context.restore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.postCompose(context, frameState, layerState);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @abstract
|
||||||
|
* @return {HTMLCanvasElement|HTMLVideoElement|Image} Canvas.
|
||||||
|
*/
|
||||||
|
ol.renderer.canvas.IntermediateCanvas.prototype.getImage = function() {};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @abstract
|
||||||
|
* @return {!ol.Transform} Image transform.
|
||||||
|
*/
|
||||||
|
ol.renderer.canvas.IntermediateCanvas.prototype.getImageTransform = function() {};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.renderer.canvas.IntermediateCanvas.prototype.forEachFeatureAtCoordinate = function(coordinate, frameState, callback, thisArg) {
|
||||||
|
var layer = this.getLayer();
|
||||||
|
var source = layer.getSource();
|
||||||
|
var resolution = frameState.viewState.resolution;
|
||||||
|
var rotation = frameState.viewState.rotation;
|
||||||
|
var skippedFeatureUids = frameState.skippedFeatureUids;
|
||||||
|
return source.forEachFeatureAtCoordinate(
|
||||||
|
coordinate, resolution, rotation, skippedFeatureUids,
|
||||||
|
/**
|
||||||
|
* @param {ol.Feature|ol.render.Feature} feature Feature.
|
||||||
|
* @return {?} Callback result.
|
||||||
|
*/
|
||||||
|
function(feature) {
|
||||||
|
return callback.call(thisArg, feature, layer);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.renderer.canvas.IntermediateCanvas.prototype.forEachLayerAtCoordinate = function(coordinate, frameState, callback, thisArg) {
|
||||||
|
if (!this.getImage()) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.getLayer().getSource().forEachFeatureAtCoordinate !== ol.nullFunction) {
|
||||||
|
// for ImageVector sources use the original hit-detection logic,
|
||||||
|
// so that for example also transparent polygons are detected
|
||||||
|
return ol.renderer.canvas.Layer.prototype.forEachLayerAtCoordinate.apply(this, arguments);
|
||||||
|
} else {
|
||||||
|
var pixel = ol.transform.apply(this.coordinateToCanvasPixelTransform, coordinate);
|
||||||
|
ol.coordinate.scale(pixel, frameState.viewState.resolution / this.renderedResolution);
|
||||||
|
|
||||||
|
if (!this.hitCanvasContext_) {
|
||||||
|
this.hitCanvasContext_ = ol.dom.createCanvasContext2D(1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.hitCanvasContext_.clearRect(0, 0, 1, 1);
|
||||||
|
this.hitCanvasContext_.drawImage(this.getImage(), pixel[0], pixel[1], 1, 1, 0, 0, 1, 1);
|
||||||
|
|
||||||
|
var imageData = this.hitCanvasContext_.getImageData(0, 0, 1, 1).data;
|
||||||
|
if (imageData[3] > 0) {
|
||||||
|
return callback.call(thisArg, this.getLayer(), imageData);
|
||||||
|
} else {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -19,6 +19,12 @@ ol.renderer.canvas.Layer = function(layer) {
|
|||||||
|
|
||||||
ol.renderer.Layer.call(this, layer);
|
ol.renderer.Layer.call(this, layer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @protected
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
this.renderedResolution;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @type {ol.Transform}
|
* @type {ol.Transform}
|
||||||
@@ -62,51 +68,6 @@ ol.renderer.canvas.Layer.prototype.clip = function(context, frameState, extent)
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {olx.FrameState} frameState Frame state.
|
|
||||||
* @param {ol.LayerState} layerState Layer state.
|
|
||||||
* @param {CanvasRenderingContext2D} context Context.
|
|
||||||
*/
|
|
||||||
ol.renderer.canvas.Layer.prototype.composeFrame = function(frameState, layerState, context) {
|
|
||||||
|
|
||||||
this.preCompose(context, frameState);
|
|
||||||
|
|
||||||
var image = this.getImage();
|
|
||||||
if (image) {
|
|
||||||
|
|
||||||
// clipped rendering if layer extent is set
|
|
||||||
var extent = layerState.extent;
|
|
||||||
var clipped = extent !== undefined;
|
|
||||||
if (clipped) {
|
|
||||||
this.clip(context, frameState, /** @type {ol.Extent} */ (extent));
|
|
||||||
}
|
|
||||||
|
|
||||||
var imageTransform = this.getImageTransform();
|
|
||||||
// for performance reasons, context.save / context.restore is not used
|
|
||||||
// to save and restore the transformation matrix and the opacity.
|
|
||||||
// see http://jsperf.com/context-save-restore-versus-variable
|
|
||||||
var alpha = context.globalAlpha;
|
|
||||||
context.globalAlpha = layerState.opacity;
|
|
||||||
|
|
||||||
// for performance reasons, context.setTransform is only used
|
|
||||||
// when the view is rotated. see http://jsperf.com/canvas-transform
|
|
||||||
var dx = imageTransform[4];
|
|
||||||
var dy = imageTransform[5];
|
|
||||||
var dw = image.width * imageTransform[0];
|
|
||||||
var dh = image.height * imageTransform[3];
|
|
||||||
context.drawImage(image, 0, 0, +image.width, +image.height,
|
|
||||||
Math.round(dx), Math.round(dy), Math.round(dw), Math.round(dh));
|
|
||||||
context.globalAlpha = alpha;
|
|
||||||
|
|
||||||
if (clipped) {
|
|
||||||
context.restore();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.postCompose(context, frameState, layerState);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {ol.render.Event.Type} type Event type.
|
* @param {ol.render.Event.Type} type Event type.
|
||||||
* @param {CanvasRenderingContext2D} context Context.
|
* @param {CanvasRenderingContext2D} context Context.
|
||||||
@@ -134,6 +95,27 @@ ol.renderer.canvas.Layer.prototype.dispatchComposeEvent_ = function(type, contex
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {ol.Coordinate} coordinate Coordinate.
|
||||||
|
* @param {olx.FrameState} frameState FrameState.
|
||||||
|
* @param {function(this: S, ol.layer.Layer, (Uint8ClampedArray|Uint8Array)): T} callback Layer
|
||||||
|
* callback.
|
||||||
|
* @param {S} thisArg Value to use as `this` when executing `callback`.
|
||||||
|
* @return {T|undefined} Callback result.
|
||||||
|
* @template S,T,U
|
||||||
|
*/
|
||||||
|
ol.renderer.canvas.Layer.prototype.forEachLayerAtCoordinate = function(coordinate, frameState, callback, thisArg) {
|
||||||
|
var hasFeature = this.forEachFeatureAtCoordinate(
|
||||||
|
coordinate, frameState, ol.functions.TRUE, this);
|
||||||
|
|
||||||
|
if (hasFeature) {
|
||||||
|
return callback.call(thisArg, this.getLayer(), null);
|
||||||
|
} else {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {CanvasRenderingContext2D} context Context.
|
* @param {CanvasRenderingContext2D} context Context.
|
||||||
* @param {olx.FrameState} frameState Frame state.
|
* @param {olx.FrameState} frameState Frame state.
|
||||||
@@ -171,20 +153,6 @@ ol.renderer.canvas.Layer.prototype.dispatchRenderEvent = function(context, frame
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @abstract
|
|
||||||
* @return {HTMLCanvasElement|HTMLVideoElement|Image} Canvas.
|
|
||||||
*/
|
|
||||||
ol.renderer.canvas.Layer.prototype.getImage = function() {};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @abstract
|
|
||||||
* @return {!ol.Transform} Image transform.
|
|
||||||
*/
|
|
||||||
ol.renderer.canvas.Layer.prototype.getImageTransform = function() {};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {olx.FrameState} frameState Frame state.
|
* @param {olx.FrameState} frameState Frame state.
|
||||||
* @param {number} offsetX Offset on the x-axis in view coordinates.
|
* @param {number} offsetX Offset on the x-axis in view coordinates.
|
||||||
@@ -205,6 +173,14 @@ ol.renderer.canvas.Layer.prototype.getTransform = function(frameState, offsetX)
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @abstract
|
||||||
|
* @param {olx.FrameState} frameState Frame state.
|
||||||
|
* @param {ol.LayerState} layerState Layer state.
|
||||||
|
* @param {CanvasRenderingContext2D} context Context.
|
||||||
|
*/
|
||||||
|
ol.renderer.canvas.Layer.prototype.composeFrame = function(frameState, layerState, context) {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @abstract
|
* @abstract
|
||||||
* @param {olx.FrameState} frameState Frame state.
|
* @param {olx.FrameState} frameState Frame state.
|
||||||
@@ -212,24 +188,3 @@ ol.renderer.canvas.Layer.prototype.getTransform = function(frameState, offsetX)
|
|||||||
* @return {boolean} whether composeFrame should be called.
|
* @return {boolean} whether composeFrame should be called.
|
||||||
*/
|
*/
|
||||||
ol.renderer.canvas.Layer.prototype.prepareFrame = function(frameState, layerState) {};
|
ol.renderer.canvas.Layer.prototype.prepareFrame = function(frameState, layerState) {};
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {ol.Coordinate} coordinate Coordinate.
|
|
||||||
* @param {olx.FrameState} frameState Frame state.
|
|
||||||
* @param {function(this: S, ol.layer.Layer, (Uint8ClampedArray|Uint8Array)): T} callback Layer callback.
|
|
||||||
* @param {S} thisArg Value to use as `this` when executing `callback`.
|
|
||||||
* @return {T|undefined} Callback result.
|
|
||||||
* @template S,T
|
|
||||||
*/
|
|
||||||
ol.renderer.canvas.Layer.prototype.forEachLayerAtCoordinate = function(coordinate, frameState, callback, thisArg) {
|
|
||||||
|
|
||||||
var hasFeature = this.forEachFeatureAtCoordinate(
|
|
||||||
coordinate, frameState, ol.functions.TRUE, this);
|
|
||||||
|
|
||||||
if (hasFeature) {
|
|
||||||
return callback.call(thisArg, this.getLayer(), null);
|
|
||||||
} else {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -9,17 +9,17 @@ goog.require('ol.Tile');
|
|||||||
goog.require('ol.array');
|
goog.require('ol.array');
|
||||||
goog.require('ol.dom');
|
goog.require('ol.dom');
|
||||||
goog.require('ol.extent');
|
goog.require('ol.extent');
|
||||||
goog.require('ol.renderer.canvas.Layer');
|
goog.require('ol.renderer.canvas.IntermediateCanvas');
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constructor
|
* @constructor
|
||||||
* @extends {ol.renderer.canvas.Layer}
|
* @extends {ol.renderer.canvas.IntermediateCanvas}
|
||||||
* @param {ol.layer.Tile|ol.layer.VectorTile} tileLayer Tile layer.
|
* @param {ol.layer.Tile|ol.layer.VectorTile} tileLayer Tile layer.
|
||||||
*/
|
*/
|
||||||
ol.renderer.canvas.TileLayer = function(tileLayer) {
|
ol.renderer.canvas.TileLayer = function(tileLayer) {
|
||||||
|
|
||||||
ol.renderer.canvas.Layer.call(this, tileLayer);
|
ol.renderer.canvas.IntermediateCanvas.call(this, tileLayer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @protected
|
* @protected
|
||||||
@@ -33,12 +33,6 @@ ol.renderer.canvas.TileLayer = function(tileLayer) {
|
|||||||
*/
|
*/
|
||||||
this.renderedExtent_ = null;
|
this.renderedExtent_ = null;
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
this.renderedResolution_;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @type {number}
|
* @type {number}
|
||||||
@@ -75,12 +69,6 @@ ol.renderer.canvas.TileLayer = function(tileLayer) {
|
|||||||
*/
|
*/
|
||||||
this.imageTransform_ = ol.transform.create();
|
this.imageTransform_ = ol.transform.create();
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {ol.Transform}
|
|
||||||
*/
|
|
||||||
this.coordinateToCanvasPixelTransform_ = ol.transform.create();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @protected
|
* @protected
|
||||||
* @type {number}
|
* @type {number}
|
||||||
@@ -88,7 +76,7 @@ ol.renderer.canvas.TileLayer = function(tileLayer) {
|
|||||||
this.zDirection = 0;
|
this.zDirection = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
ol.inherits(ol.renderer.canvas.TileLayer, ol.renderer.canvas.Layer);
|
ol.inherits(ol.renderer.canvas.TileLayer, ol.renderer.canvas.IntermediateCanvas);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -172,7 +160,7 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame = function(frameState, layer
|
|||||||
}
|
}
|
||||||
|
|
||||||
var hints = frameState.viewHints;
|
var hints = frameState.viewHints;
|
||||||
if (!(this.renderedResolution_ && Date.now() - frameState.time > 16 &&
|
if (!(this.renderedResolution && Date.now() - frameState.time > 16 &&
|
||||||
(hints[ol.View.Hint.ANIMATING] || hints[ol.View.Hint.INTERACTING])) &&
|
(hints[ol.View.Hint.ANIMATING] || hints[ol.View.Hint.INTERACTING])) &&
|
||||||
(newTiles || !(this.renderedExtent_ &&
|
(newTiles || !(this.renderedExtent_ &&
|
||||||
ol.extent.equals(this.renderedExtent_, imageExtent)) ||
|
ol.extent.equals(this.renderedExtent_, imageExtent)) ||
|
||||||
@@ -220,18 +208,18 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame = function(frameState, layer
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.renderedRevision_ = sourceRevision;
|
this.renderedRevision_ = sourceRevision;
|
||||||
this.renderedResolution_ = tileResolution;
|
this.renderedResolution = tileResolution;
|
||||||
this.renderedExtent_ = imageExtent;
|
this.renderedExtent_ = imageExtent;
|
||||||
}
|
}
|
||||||
|
|
||||||
var scale = pixelRatio / tilePixelRatio * this.renderedResolution_ / viewResolution;
|
var scale = pixelRatio / tilePixelRatio * this.renderedResolution / viewResolution;
|
||||||
var transform = ol.transform.compose(this.imageTransform_,
|
var transform = ol.transform.compose(this.imageTransform_,
|
||||||
pixelRatio * size[0] / 2, pixelRatio * size[1] / 2,
|
pixelRatio * size[0] / 2, pixelRatio * size[1] / 2,
|
||||||
scale, scale,
|
scale, scale,
|
||||||
0,
|
0,
|
||||||
tilePixelRatio * (this.renderedExtent_[0] - viewCenter[0]) / this.renderedResolution_,
|
tilePixelRatio * (this.renderedExtent_[0] - viewCenter[0]) / this.renderedResolution,
|
||||||
tilePixelRatio * (viewCenter[1] - this.renderedExtent_[3]) / this.renderedResolution_);
|
tilePixelRatio * (viewCenter[1] - this.renderedExtent_[3]) / this.renderedResolution);
|
||||||
ol.transform.compose(this.coordinateToCanvasPixelTransform_,
|
ol.transform.compose(this.coordinateToCanvasPixelTransform,
|
||||||
pixelRatio * size[0] / 2 - transform[4], pixelRatio * size[1] / 2 - transform[5],
|
pixelRatio * size[0] / 2 - transform[4], pixelRatio * size[1] / 2 - transform[5],
|
||||||
pixelRatio / viewResolution, -pixelRatio / viewResolution,
|
pixelRatio / viewResolution, -pixelRatio / viewResolution,
|
||||||
0,
|
0,
|
||||||
@@ -267,29 +255,6 @@ ol.renderer.canvas.TileLayer.prototype.drawTileImage = function(tile, frameState
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {ol.Coordinate} coordinate Coordinate.
|
|
||||||
* @param {olx.FrameState} frameState FrameState.
|
|
||||||
* @param {function(this: S, ol.layer.Layer, (Uint8ClampedArray|Uint8Array)): T} callback Layer
|
|
||||||
* callback.
|
|
||||||
* @param {S} thisArg Value to use as `this` when executing `callback`.
|
|
||||||
* @return {T|undefined} Callback result.
|
|
||||||
* @template S,T,U
|
|
||||||
*/
|
|
||||||
ol.renderer.canvas.TileLayer.prototype.forEachLayerAtCoordinate = function(
|
|
||||||
coordinate, frameState, callback, thisArg) {
|
|
||||||
var canvasPixel = ol.transform.apply(this.coordinateToCanvasPixelTransform_, coordinate);
|
|
||||||
|
|
||||||
var imageData = this.context.getImageData(canvasPixel[0], canvasPixel[1], 1, 1).data;
|
|
||||||
if (imageData[3] > 0) {
|
|
||||||
return callback.call(thisArg, this.getLayer(), imageData);
|
|
||||||
} else {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -3,17 +3,17 @@ goog.provide('ol.test.renderer.canvas.Layer');
|
|||||||
goog.require('ol.transform');
|
goog.require('ol.transform');
|
||||||
goog.require('ol.layer.Image');
|
goog.require('ol.layer.Image');
|
||||||
goog.require('ol.renderer.Map');
|
goog.require('ol.renderer.Map');
|
||||||
goog.require('ol.renderer.canvas.Layer');
|
goog.require('ol.renderer.canvas.IntermediateCanvas');
|
||||||
|
|
||||||
|
|
||||||
describe('ol.renderer.canvas.Layer', function() {
|
describe('ol.renderer.canvas.IntermediateCanvas', function() {
|
||||||
|
|
||||||
describe('#composeFrame()', function() {
|
describe('#composeFrame()', function() {
|
||||||
it('clips to layer extent and draws image', function() {
|
it('clips to layer extent and draws image', function() {
|
||||||
var layer = new ol.layer.Image({
|
var layer = new ol.layer.Image({
|
||||||
extent: [1, 2, 3, 4]
|
extent: [1, 2, 3, 4]
|
||||||
});
|
});
|
||||||
var renderer = new ol.renderer.canvas.Layer(layer);
|
var renderer = new ol.renderer.canvas.IntermediateCanvas(layer);
|
||||||
var image = new Image();
|
var image = new Image();
|
||||||
image.width = 3;
|
image.width = 3;
|
||||||
image.height = 3;
|
image.height = 3;
|
||||||
Reference in New Issue
Block a user