diff --git a/src/ol/renderer/canvas/imagelayer.js b/src/ol/renderer/canvas/imagelayer.js index 1b2111f537..6dbf8d4abd 100644 --- a/src/ol/renderer/canvas/imagelayer.js +++ b/src/ol/renderer/canvas/imagelayer.js @@ -70,7 +70,7 @@ ol.renderer.canvas.ImageLayer.prototype.forEachFeatureAtCoordinate = function(co /** - * @param {ol.Pixel} pixel Pixel. + * @param {ol.Coordinate} coordinate Coordinate. * @param {olx.FrameState} frameState FrameState. * @param {function(this: S, ol.layer.Layer, (Uint8ClampedArray|Uint8Array)): T} callback Layer * callback. @@ -78,7 +78,7 @@ ol.renderer.canvas.ImageLayer.prototype.forEachFeatureAtCoordinate = function(co * @return {T|undefined} Callback result. * @template S,T,U */ -ol.renderer.canvas.ImageLayer.prototype.forEachLayerAtPixel = function(pixel, frameState, callback, thisArg) { +ol.renderer.canvas.ImageLayer.prototype.forEachLayerAtCoordinate = function(coordinate, frameState, callback, thisArg) { if (!this.getImage()) { return undefined; } @@ -86,8 +86,6 @@ ol.renderer.canvas.ImageLayer.prototype.forEachLayerAtPixel = function(pixel, fr 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 coordinate = ol.transform.apply( - frameState.pixelToCoordinateTransform, pixel.slice()); var hasFeature = this.forEachFeatureAtCoordinate( coordinate, frameState, ol.functions.TRUE, this); @@ -97,13 +95,8 @@ ol.renderer.canvas.ImageLayer.prototype.forEachLayerAtPixel = function(pixel, fr return undefined; } } else { - // for all other image sources directly check the image - if (!this.imageTransformInv_) { - this.imageTransformInv_ = ol.transform.invert(this.imageTransform_.slice()); - } - - var pixelOnCanvas = - this.getPixelOnCanvas(pixel, this.imageTransformInv_); + var pixelOnCanvas = ol.transform.apply( + this.coordinateToCanvasPixelTransform_, coordinate.slice()); if (!this.hitCanvasContext_) { this.hitCanvasContext_ = ol.dom.createCanvasContext2D(1, 1); @@ -145,6 +138,7 @@ ol.renderer.canvas.ImageLayer.prototype.getImageTransform = function() { ol.renderer.canvas.ImageLayer.prototype.prepareFrame = function(frameState, layerState) { var pixelRatio = frameState.pixelRatio; + var size = frameState.size; var viewState = frameState.viewState; var viewCenter = viewState.center; var viewResolution = viewState.resolution; @@ -197,7 +191,11 @@ ol.renderer.canvas.ImageLayer.prototype.prepareFrame = function(frameState, laye ol.transform.translate(transform, imagePixelRatio * (imageExtent[0] - viewCenter[0]) / imageResolution, imagePixelRatio * (viewCenter[1] - imageExtent[3]) / imageResolution); - this.imageTransformInv_ = null; + ol.transform.compose(ol.transform.reset(this.coordinateToCanvasPixelTransform_), + pixelRatio * size[0] / 2 - transform[4], pixelRatio * size[1] / 2 - transform[5], + pixelRatio / viewResolution, -pixelRatio / viewResolution, + 0, + -viewCenter[0], -viewCenter[1]); this.updateAttributions(frameState.attributions, image.getAttributions()); this.updateLogos(frameState, imageSource); } diff --git a/src/ol/renderer/canvas/layer.js b/src/ol/renderer/canvas/layer.js index a9df0e7dea..5ffb9e1f93 100644 --- a/src/ol/renderer/canvas/layer.js +++ b/src/ol/renderer/canvas/layer.js @@ -2,6 +2,7 @@ goog.provide('ol.renderer.canvas.Layer'); goog.require('ol'); goog.require('ol.extent'); +goog.require('ol.functions'); goog.require('ol.render.Event'); goog.require('ol.render.canvas'); goog.require('ol.render.canvas.Immediate'); @@ -214,12 +215,21 @@ ol.renderer.canvas.Layer.prototype.prepareFrame = function(frameState, layerStat /** - * @param {ol.Pixel} pixelOnMap Pixel. - * @param {ol.Transform} imageTransformInv The transformation matrix - * to convert from a map pixel to a canvas pixel. - * @return {ol.Pixel} The pixel. - * @protected + * @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.getPixelOnCanvas = function(pixelOnMap, imageTransformInv) { - return ol.transform.apply(imageTransformInv, pixelOnMap.slice()); +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; + } }; diff --git a/src/ol/renderer/canvas/map.js b/src/ol/renderer/canvas/map.js index 6dcb6a10a6..3e78ec20ab 100644 --- a/src/ol/renderer/canvas/map.js +++ b/src/ol/renderer/canvas/map.js @@ -200,3 +200,36 @@ ol.renderer.canvas.Map.prototype.renderFrame = function(frameState) { this.scheduleRemoveUnusedLayerRenderers(frameState); this.scheduleExpireIconCache(frameState); }; + + +/** + * @inheritDoc + */ +ol.renderer.canvas.Map.prototype.forEachLayerAtPixel = function(pixel, frameState, callback, thisArg, + layerFilter, thisArg2) { + var result; + var viewState = frameState.viewState; + var viewResolution = viewState.resolution; + + var layerStates = frameState.layerStatesArray; + var numLayers = layerStates.length; + + var coordinate = ol.transform.apply( + frameState.pixelToCoordinateTransform, pixel.slice()); + + var i; + for (i = numLayers - 1; i >= 0; --i) { + var layerState = layerStates[i]; + var layer = layerState.layer; + if (ol.layer.Layer.visibleAtResolution(layerState, viewResolution) && + layerFilter.call(thisArg2, layer)) { + var layerRenderer = /** @type {ol.renderer.canvas.Layer} */ (this.getLayerRenderer(layer)); + result = layerRenderer.forEachLayerAtCoordinate( + coordinate, frameState, callback, thisArg); + if (result) { + return result; + } + } + } + return undefined; +}; diff --git a/src/ol/renderer/canvas/tilelayer.js b/src/ol/renderer/canvas/tilelayer.js index bf502c2bc6..06b6aa6b98 100644 --- a/src/ol/renderer/canvas/tilelayer.js +++ b/src/ol/renderer/canvas/tilelayer.js @@ -249,7 +249,7 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame = function( /** - * @param {ol.Pixel} pixel Pixel. + * @param {ol.Coordinate} coordinate Coordinate. * @param {olx.FrameState} frameState FrameState. * @param {function(this: S, ol.layer.Layer, (Uint8ClampedArray|Uint8Array)): T} callback Layer * callback. @@ -257,9 +257,8 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame = function( * @return {T|undefined} Callback result. * @template S,T,U */ -ol.renderer.canvas.TileLayer.prototype.forEachLayerAtPixel = function( - pixel, frameState, callback, thisArg) { - var coordinate = ol.transform.apply(frameState.pixelToCoordinateTransform, pixel.slice()); +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; diff --git a/src/ol/renderer/layer.js b/src/ol/renderer/layer.js index f6c603b8a4..2e96ea86d3 100644 --- a/src/ol/renderer/layer.js +++ b/src/ol/renderer/layer.js @@ -9,7 +9,6 @@ goog.require('ol.events'); goog.require('ol.events.EventType'); goog.require('ol.functions'); goog.require('ol.source.State'); -goog.require('ol.transform'); /** @@ -45,29 +44,6 @@ ol.inherits(ol.renderer.Layer, ol.Observable); ol.renderer.Layer.prototype.forEachFeatureAtCoordinate = ol.nullFunction; -/** - * @param {ol.Pixel} pixel Pixel. - * @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.Layer.prototype.forEachLayerAtPixel = function(pixel, frameState, callback, thisArg) { - var coordinate = ol.transform.apply( - frameState.pixelToCoordinateTransform, pixel.slice()); - - var hasFeature = this.forEachFeatureAtCoordinate( - coordinate, frameState, ol.functions.TRUE, this); - - if (hasFeature) { - return callback.call(thisArg, this.layer_, null); - } else { - return undefined; - } -}; - - /** * @param {ol.Coordinate} coordinate Coordinate. * @param {olx.FrameState} frameState Frame state. diff --git a/src/ol/renderer/map.js b/src/ol/renderer/map.js index a8e88f804e..e9f0d8bae0 100644 --- a/src/ol/renderer/map.js +++ b/src/ol/renderer/map.js @@ -167,6 +167,7 @@ ol.renderer.Map.prototype.forEachFeatureAtCoordinate = function(coordinate, fram /** + * @abstract * @param {ol.Pixel} pixel Pixel. * @param {olx.FrameState} frameState FrameState. * @param {function(this: S, ol.layer.Layer, (Uint8ClampedArray|Uint8Array)): T} callback Layer @@ -181,29 +182,7 @@ ol.renderer.Map.prototype.forEachFeatureAtCoordinate = function(coordinate, fram * @template S,T,U */ ol.renderer.Map.prototype.forEachLayerAtPixel = function(pixel, frameState, callback, thisArg, - layerFilter, thisArg2) { - var result; - var viewState = frameState.viewState; - var viewResolution = viewState.resolution; - - var layerStates = frameState.layerStatesArray; - var numLayers = layerStates.length; - var i; - for (i = numLayers - 1; i >= 0; --i) { - var layerState = layerStates[i]; - var layer = layerState.layer; - if (ol.layer.Layer.visibleAtResolution(layerState, viewResolution) && - layerFilter.call(thisArg2, layer)) { - var layerRenderer = this.getLayerRenderer(layer); - result = layerRenderer.forEachLayerAtPixel( - pixel, frameState, callback, thisArg); - if (result) { - return result; - } - } - } - return undefined; -}; + layerFilter, thisArg2) {}; /** diff --git a/src/ol/renderer/webgl/imagelayer.js b/src/ol/renderer/webgl/imagelayer.js index 8e7507ef9d..8df0c036df 100644 --- a/src/ol/renderer/webgl/imagelayer.js +++ b/src/ol/renderer/webgl/imagelayer.js @@ -219,13 +219,7 @@ ol.renderer.webgl.ImageLayer.prototype.hasFeatureAtCoordinate = function(coordin /** - * @param {ol.Pixel} pixel Pixel. - * @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 + * @inheritDoc */ ol.renderer.webgl.ImageLayer.prototype.forEachLayerAtPixel = function(pixel, frameState, callback, thisArg) { if (!this.image_ || !this.image_.getImage()) { diff --git a/src/ol/renderer/webgl/layer.js b/src/ol/renderer/webgl/layer.js index e6f7da508d..1dd5ae61dd 100644 --- a/src/ol/renderer/webgl/layer.js +++ b/src/ol/renderer/webgl/layer.js @@ -251,3 +251,16 @@ ol.renderer.webgl.Layer.prototype.handleWebGLContextLost = function() { * @return {boolean} whether composeFrame should be called. */ ol.renderer.webgl.Layer.prototype.prepareFrame = function(frameState, layerState, context) {}; + + +/** + * @abstract + * @param {ol.Pixel} pixel Pixel. + * @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.webgl.Layer.prototype.forEachLayerAtPixel = function(pixel, frameState, callback, thisArg) {}; diff --git a/src/ol/renderer/webgl/map.js b/src/ol/renderer/webgl/map.js index e055609ff6..5844610adf 100644 --- a/src/ol/renderer/webgl/map.js +++ b/src/ol/renderer/webgl/map.js @@ -584,7 +584,7 @@ ol.renderer.webgl.Map.prototype.forEachLayerAtPixel = function(pixel, frameState var layer = layerState.layer; if (ol.layer.Layer.visibleAtResolution(layerState, viewState.resolution) && layerFilter.call(thisArg, layer)) { - var layerRenderer = this.getLayerRenderer(layer); + var layerRenderer = /** @type {ol.renderer.webgl.Layer} */ (this.getLayerRenderer(layer)); result = layerRenderer.forEachLayerAtPixel( pixel, frameState, callback, thisArg); if (result) { diff --git a/src/ol/renderer/webgl/tilelayer.js b/src/ol/renderer/webgl/tilelayer.js index b7e958a1b2..824f7d3303 100644 --- a/src/ol/renderer/webgl/tilelayer.js +++ b/src/ol/renderer/webgl/tilelayer.js @@ -358,13 +358,7 @@ ol.renderer.webgl.TileLayer.prototype.prepareFrame = function(frameState, layerS /** - * @param {ol.Pixel} pixel Pixel. - * @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 + * @inheritDoc */ ol.renderer.webgl.TileLayer.prototype.forEachLayerAtPixel = function(pixel, frameState, callback, thisArg) { if (!this.framebuffer) { diff --git a/src/ol/renderer/webgl/vectorlayer.js b/src/ol/renderer/webgl/vectorlayer.js index 494d5eb149..d94975f8a6 100644 --- a/src/ol/renderer/webgl/vectorlayer.js +++ b/src/ol/renderer/webgl/vectorlayer.js @@ -154,13 +154,7 @@ ol.renderer.webgl.VectorLayer.prototype.hasFeatureAtCoordinate = function(coordi /** - * @param {ol.Pixel} pixel Pixel. - * @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 + * @inheritDoc */ ol.renderer.webgl.VectorLayer.prototype.forEachLayerAtPixel = function(pixel, frameState, callback, thisArg) { var coordinate = ol.transform.apply(