Implement forEachLayerAtPixel for canvas
This commit is contained in:
@@ -4,11 +4,13 @@ goog.require('goog.asserts');
|
||||
goog.require('goog.vec.Mat4');
|
||||
goog.require('ol.ImageBase');
|
||||
goog.require('ol.ViewHint');
|
||||
goog.require('ol.dom');
|
||||
goog.require('ol.extent');
|
||||
goog.require('ol.layer.Image');
|
||||
goog.require('ol.proj');
|
||||
goog.require('ol.renderer.Map');
|
||||
goog.require('ol.renderer.canvas.Layer');
|
||||
goog.require('ol.source.ImageVector');
|
||||
goog.require('ol.vec.Mat4');
|
||||
|
||||
|
||||
@@ -35,6 +37,18 @@ ol.renderer.canvas.ImageLayer = function(mapRenderer, imageLayer) {
|
||||
*/
|
||||
this.imageTransform_ = goog.vec.Mat4.createNumber();
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {?goog.vec.Mat4.Number}
|
||||
*/
|
||||
this.imageTransformInv_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {CanvasRenderingContext2D}
|
||||
*/
|
||||
this.hitCanvasContext_ = null;
|
||||
|
||||
};
|
||||
goog.inherits(ol.renderer.canvas.ImageLayer, ol.renderer.canvas.Layer);
|
||||
|
||||
@@ -61,6 +75,54 @@ ol.renderer.canvas.ImageLayer.prototype.forEachFeatureAtPixel =
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.canvas.ImageLayer.prototype.forEachLayerAtPixel =
|
||||
function(coordinate, frameState, callback, thisArg) {
|
||||
if (goog.isNull(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.forEachFeatureAtPixel(
|
||||
coordinate, frameState, goog.functions.TRUE, this);
|
||||
|
||||
if (hasFeature) {
|
||||
return callback.call(thisArg, this.getLayer());
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
} else {
|
||||
// for all other image sources directly check the image
|
||||
if (goog.isNull(this.imageTransformInv_)) {
|
||||
this.imageTransformInv_ = goog.vec.Mat4.createNumber();
|
||||
goog.vec.Mat4.invert(this.imageTransform_, this.imageTransformInv_);
|
||||
}
|
||||
|
||||
var pixelOnCanvas =
|
||||
this.getPixelFromCoordinates(coordinate, this.imageTransformInv_);
|
||||
|
||||
if (goog.isNull(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());
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@@ -135,6 +197,7 @@ ol.renderer.canvas.ImageLayer.prototype.prepareFrame =
|
||||
viewRotation,
|
||||
imagePixelRatio * (imageExtent[0] - viewCenter[0]) / imageResolution,
|
||||
imagePixelRatio * (viewCenter[1] - imageExtent[3]) / imageResolution);
|
||||
this.imageTransformInv_ = null;
|
||||
this.updateAttributions(frameState.attributions, image.getAttributions());
|
||||
this.updateLogos(frameState, imageSource);
|
||||
}
|
||||
|
||||
@@ -216,6 +216,22 @@ ol.renderer.canvas.Layer.prototype.getTransform = function(frameState) {
|
||||
ol.renderer.canvas.Layer.prototype.prepareFrame = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Coordinate} coordinate Coordinate.
|
||||
* @param {goog.vec.Mat4.Number} imageTransformInv The transformation matrix
|
||||
* to convert from a map pixel to a canvas pixel.
|
||||
* @return {ol.Pixel}
|
||||
* @protected
|
||||
*/
|
||||
ol.renderer.canvas.Layer.prototype.getPixelFromCoordinates =
|
||||
function(coordinate, imageTransformInv) {
|
||||
var pixelOnMap = this.getMap().getPixelFromCoordinate(coordinate);
|
||||
var pixelOnCanvas = [0, 0];
|
||||
ol.vec.Mat4.multVec2(imageTransformInv, pixelOnMap, pixelOnCanvas);
|
||||
return pixelOnCanvas;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Size} size Size.
|
||||
* @return {boolean} True when the canvas with the current size does not exceed
|
||||
|
||||
@@ -60,6 +60,12 @@ ol.renderer.canvas.TileLayer = function(mapRenderer, tileLayer) {
|
||||
*/
|
||||
this.imageTransform_ = goog.vec.Mat4.createNumber();
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {?goog.vec.Mat4.Number}
|
||||
*/
|
||||
this.imageTransformInv_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
@@ -408,6 +414,35 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame =
|
||||
viewState.rotation,
|
||||
(origin[0] - center[0]) / tilePixelResolution,
|
||||
(center[1] - origin[1]) / tilePixelResolution);
|
||||
this.imageTransformInv_ = null;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.canvas.TileLayer.prototype.forEachLayerAtPixel =
|
||||
function(coordinate, frameState, callback, thisArg) {
|
||||
if (goog.isNull(this.context_)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (goog.isNull(this.imageTransformInv_)) {
|
||||
this.imageTransformInv_ = goog.vec.Mat4.createNumber();
|
||||
goog.vec.Mat4.invert(this.imageTransform_, this.imageTransformInv_);
|
||||
}
|
||||
|
||||
var pixelOnCanvas =
|
||||
this.getPixelFromCoordinates(coordinate, this.imageTransformInv_);
|
||||
|
||||
var imageData = this.context_.getImageData(
|
||||
pixelOnCanvas[0], pixelOnCanvas[1], 1, 1).data;
|
||||
|
||||
if (imageData[3] > 0) {
|
||||
return callback.call(thisArg, this.getLayer());
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user