diff --git a/changelog/upgrade-notes.md b/changelog/upgrade-notes.md index 478c58eff3..b69be2d8ed 100644 --- a/changelog/upgrade-notes.md +++ b/changelog/upgrade-notes.md @@ -4,6 +4,23 @@ #### Backwards incompatible changes +##### Usage of `Map.forEachLayerAtPixel` + +Due to performance considerations, the layers in a map will sometimes be rendered into one +single canvas instead of separate elements. +This means `Map.forEachLayerAtPixel` will bring up false positives. + +The easiest solution to avoid that is to assign different `className` properties to each layer like so: +```js +new Layer({ + // ... + className: 'my-layer' +}) +``` + +Please note that this may incur a significant performance loss when dealing with many layers and/or +targetting mobile devices. + ##### Removal of `TOUCH` constant from `ol/has` If you were previously using this constant, you can check if `'ontouchstart'` is defined in `window` instead. diff --git a/src/ol/PluggableMap.js b/src/ol/PluggableMap.js index 6e5e14391d..09c540e418 100644 --- a/src/ol/PluggableMap.js +++ b/src/ol/PluggableMap.js @@ -595,6 +595,10 @@ class PluggableMap extends BaseObject { * Detect layers that have a color value at a pixel on the viewport, and * execute a callback with each matching layer. Layers included in the * detection can be configured through `opt_layerFilter`. + * + * Note: this may give false positives unless the map layers have had different `className` + * properties assigned to them. + * * @param {import("./pixel.js").Pixel} pixel Pixel. * @param {function(this: S, import("./layer/Layer.js").default, (Uint8ClampedArray|Uint8Array)): T} callback * Layer callback. This callback will receive two arguments: first is the diff --git a/src/ol/layer/Layer.js b/src/ol/layer/Layer.js index 4665dafdb9..58f2ef44f2 100644 --- a/src/ol/layer/Layer.js +++ b/src/ol/layer/Layer.js @@ -35,6 +35,7 @@ import SourceState from '../source/State.js'; * @property {import("../PluggableMap.js").default} [map] Map. * @property {RenderFunction} [render] Render function. Takes the frame state as input and is expected to return an * HTML element. Will overwrite the default rendering for the layer. + * @property {string} [className='ol-layer'] A CSS class name to set to the layer element. */ @@ -71,6 +72,11 @@ import SourceState from '../source/State.js'; * * A generic `change` event is fired when the state of the source changes. * + * Please note that for performance reasons several layers might get rendered to + * the same HTML element, which will cause {@link module:ol/Map~Map#forEachLayerAtPixel} to + * give false positives. To avoid this, apply different `className` properties to the + * layers at creation time. + * * @fires import("../render/Event.js").RenderEvent#prerender * @fires import("../render/Event.js").RenderEvent#postrender *