Implement forEachLayerAtPixel for canvas
This commit is contained in:
@@ -4,11 +4,13 @@ goog.require('goog.asserts');
|
|||||||
goog.require('goog.vec.Mat4');
|
goog.require('goog.vec.Mat4');
|
||||||
goog.require('ol.ImageBase');
|
goog.require('ol.ImageBase');
|
||||||
goog.require('ol.ViewHint');
|
goog.require('ol.ViewHint');
|
||||||
|
goog.require('ol.dom');
|
||||||
goog.require('ol.extent');
|
goog.require('ol.extent');
|
||||||
goog.require('ol.layer.Image');
|
goog.require('ol.layer.Image');
|
||||||
goog.require('ol.proj');
|
goog.require('ol.proj');
|
||||||
goog.require('ol.renderer.Map');
|
goog.require('ol.renderer.Map');
|
||||||
goog.require('ol.renderer.canvas.Layer');
|
goog.require('ol.renderer.canvas.Layer');
|
||||||
|
goog.require('ol.source.ImageVector');
|
||||||
goog.require('ol.vec.Mat4');
|
goog.require('ol.vec.Mat4');
|
||||||
|
|
||||||
|
|
||||||
@@ -35,6 +37,18 @@ ol.renderer.canvas.ImageLayer = function(mapRenderer, imageLayer) {
|
|||||||
*/
|
*/
|
||||||
this.imageTransform_ = goog.vec.Mat4.createNumber();
|
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);
|
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
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
@@ -135,6 +197,7 @@ ol.renderer.canvas.ImageLayer.prototype.prepareFrame =
|
|||||||
viewRotation,
|
viewRotation,
|
||||||
imagePixelRatio * (imageExtent[0] - viewCenter[0]) / imageResolution,
|
imagePixelRatio * (imageExtent[0] - viewCenter[0]) / imageResolution,
|
||||||
imagePixelRatio * (viewCenter[1] - imageExtent[3]) / imageResolution);
|
imagePixelRatio * (viewCenter[1] - imageExtent[3]) / imageResolution);
|
||||||
|
this.imageTransformInv_ = null;
|
||||||
this.updateAttributions(frameState.attributions, image.getAttributions());
|
this.updateAttributions(frameState.attributions, image.getAttributions());
|
||||||
this.updateLogos(frameState, imageSource);
|
this.updateLogos(frameState, imageSource);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -216,6 +216,22 @@ ol.renderer.canvas.Layer.prototype.getTransform = function(frameState) {
|
|||||||
ol.renderer.canvas.Layer.prototype.prepareFrame = goog.abstractMethod;
|
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.
|
* @param {ol.Size} size Size.
|
||||||
* @return {boolean} True when the canvas with the current size does not exceed
|
* @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();
|
this.imageTransform_ = goog.vec.Mat4.createNumber();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {?goog.vec.Mat4.Number}
|
||||||
|
*/
|
||||||
|
this.imageTransformInv_ = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @type {number}
|
* @type {number}
|
||||||
@@ -408,6 +414,35 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame =
|
|||||||
viewState.rotation,
|
viewState.rotation,
|
||||||
(origin[0] - center[0]) / tilePixelResolution,
|
(origin[0] - center[0]) / tilePixelResolution,
|
||||||
(center[1] - origin[1]) / tilePixelResolution);
|
(center[1] - origin[1]) / tilePixelResolution);
|
||||||
|
this.imageTransformInv_ = null;
|
||||||
|
|
||||||
return true;
|
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