diff --git a/examples/offscreen-canvas.worker.js b/examples/offscreen-canvas.worker.js index ce33a656c5..f37f334743 100644 --- a/examples/offscreen-canvas.worker.js +++ b/examples/offscreen-canvas.worker.js @@ -6,7 +6,6 @@ import stringify from 'json-stringify-safe'; import styleFunction from 'ol-mapbox-style/dist/stylefunction.js'; import {Projection} from '../src/ol/proj.js'; import {inView} from '../src/ol/layer/Layer.js'; -import {renderDeclutterItems} from '../src/ol/render.js'; import {getTilePriority as tilePriorityFunction} from '../src/ol/TileQueue.js'; /** @type {any} */ @@ -145,7 +144,6 @@ worker.addEventListener('message', (event) => { renderer.renderFrame(frameState, canvas); } }); - renderDeclutterItems(frameState, null); if (tileQueue.getTilesLoading() < maxTotalLoading) { tileQueue.reprioritize(); tileQueue.loadMoreTiles(maxTotalLoading, maxNewLoads); diff --git a/src/ol/PluggableMap.js b/src/ol/PluggableMap.js index d25adf8d21..3bf3509ea7 100644 --- a/src/ol/PluggableMap.js +++ b/src/ol/PluggableMap.js @@ -51,7 +51,6 @@ import {removeNode} from './dom.js'; * @property {boolean} animate * @property {import("./transform.js").Transform} coordinateToPixelTransform * @property {null|import("./extent.js").Extent} extent - * @property {Array} declutterItems * @property {number} index * @property {Array} layerStatesArray * @property {number} layerIndex @@ -64,12 +63,6 @@ import {removeNode} from './dom.js'; * @property {!Object>} wantedTiles */ -/** - * @typedef {Object} DeclutterItems - * @property {Array<*>} items Declutter items of an executor. - * @property {number} opacity Layer opacity. - */ - /** * @typedef {function(PluggableMap, ?FrameState): any} PostRenderFunction */ @@ -1379,9 +1372,6 @@ class PluggableMap extends BaseObject { frameState = { animate: false, coordinateToPixelTransform: this.coordinateToPixelTransform_, - declutterItems: previousFrameState - ? previousFrameState.declutterItems - : [], extent: getForViewAndSize( viewState.center, viewState.resolution, diff --git a/src/ol/render.js b/src/ol/render.js index f964ec5469..22ecd658ae 100644 --- a/src/ol/render.js +++ b/src/ol/render.js @@ -129,29 +129,3 @@ export function getRenderPixel(event, pixel) { applyTransform(event.inversePixelTransform.slice(), result); return result; } - -/** - * @param {import("./PluggableMap.js").FrameState} frameState Frame state. - * @param {?} declutterTree Declutter tree. - * @returns {?} Declutter tree. - */ -export function renderDeclutterItems(frameState, declutterTree) { - if (declutterTree) { - declutterTree.clear(); - } - const items = frameState.declutterItems; - for (let z = items.length - 1; z >= 0; --z) { - const item = items[z]; - const zIndexItems = item.items; - for (let i = 0, ii = zIndexItems.length; i < ii; i += 3) { - declutterTree = zIndexItems[i].renderDeclutter( - zIndexItems[i + 1], - zIndexItems[i + 2], - item.opacity, - declutterTree - ); - } - } - items.length = 0; - return declutterTree; -} diff --git a/src/ol/render/VectorContext.js b/src/ol/render/VectorContext.js index e00d586363..4fc3a1f39e 100644 --- a/src/ol/render/VectorContext.js +++ b/src/ol/render/VectorContext.js @@ -100,15 +100,13 @@ class VectorContext { /** * @param {import("../style/Image.js").default} imageStyle Image style. - * @param {import("./canvas.js").DeclutterGroup=} opt_declutterGroup Declutter. */ - setImageStyle(imageStyle, opt_declutterGroup) {} + setImageStyle(imageStyle) {} /** * @param {import("../style/Text.js").default} textStyle Text style. - * @param {import("./canvas.js").DeclutterGroups=} opt_declutterGroups Declutter. */ - setTextStyle(textStyle, opt_declutterGroups) {} + setTextStyle(textStyle) {} } export default VectorContext; diff --git a/src/ol/render/canvas.js b/src/ol/render/canvas.js index 97cf9df9f5..7c4b00db70 100644 --- a/src/ol/render/canvas.js +++ b/src/ol/render/canvas.js @@ -67,23 +67,6 @@ import {toString} from '../transform.js'; * @property {Array} [padding] */ -/** - * Container for decluttered replay instructions that need to be rendered or - * omitted together, i.e. when styles render both an image and text, or for the - * characters that form text along lines. The basic elements of this array are - * `[minX, minY, maxX, maxY, count]`, where the first four entries are the - * rendered extent of the group in pixel space. `count` is the number of styles - * in the group, i.e. 2 when an image and a text are grouped, or 1 otherwise. - * In addition to these four elements, declutter instruction arrays (i.e. the - * arguments to {@link module:ol/render/canvas~drawImage} are appended to the array. - * @typedef {Array<*>} DeclutterGroup - */ - -/** - * Declutter groups for support of multi geometries. - * @typedef {Array} DeclutterGroups - */ - /** * @const * @type {string} diff --git a/src/ol/render/canvas/BuilderGroup.js b/src/ol/render/canvas/BuilderGroup.js index d588727215..49aa6c44c5 100644 --- a/src/ol/render/canvas/BuilderGroup.js +++ b/src/ol/render/canvas/BuilderGroup.js @@ -26,21 +26,8 @@ class BuilderGroup { * @param {import("../../extent.js").Extent} maxExtent Max extent. * @param {number} resolution Resolution. * @param {number} pixelRatio Pixel ratio. - * @param {boolean} declutter Decluttering enabled. */ - constructor(tolerance, maxExtent, resolution, pixelRatio, declutter) { - /** - * @type {boolean} - * @private - */ - this.declutter_ = declutter; - - /** - * @type {import("../canvas.js").DeclutterGroups} - * @private - */ - this.declutterGroups_ = null; - + constructor(tolerance, maxExtent, resolution, pixelRatio) { /** * @private * @type {number} @@ -72,25 +59,6 @@ class BuilderGroup { this.buildersByZIndex_ = {}; } - /** - * @param {boolean} group Group with previous builder. - * @return {import("../canvas").DeclutterGroups} The resulting instruction groups. - */ - addDeclutter(group) { - /** @type {Array<*>} */ - let declutter = null; - if (this.declutter_) { - if (group) { - declutter = this.declutterGroups_; - /** @type {number} */ (declutter[0][0])++; - } else { - declutter = [[1]]; - this.declutterGroups_ = declutter; - } - } - return declutter; - } - /** * @return {!Object>} The serializable instructions */ diff --git a/src/ol/render/canvas/Executor.js b/src/ol/render/canvas/Executor.js index 461bbd3896..b37ca24863 100644 --- a/src/ol/render/canvas/Executor.js +++ b/src/ol/render/canvas/Executor.js @@ -2,7 +2,6 @@ * @module ol/render/canvas/Executor */ import CanvasInstruction from './Instruction.js'; -import RBush from 'rbush'; import {TEXT_ALIGN} from './TextBuilder.js'; import {WORKER_OFFSCREEN_CANVAS} from '../../has.js'; import { @@ -11,13 +10,7 @@ import { create as createTransform, setFromArray as transformSetFromArray, } from '../../transform.js'; -import { - createEmpty, - createOrUpdate, - getHeight, - getWidth, - intersects, -} from '../../extent.js'; +import {createEmpty, createOrUpdate, intersects} from '../../extent.js'; import { defaultPadding, defaultTextBaseline, @@ -97,11 +90,6 @@ class Executor { */ this.alignFill_; - /** - * @type {Array<*>} - */ - this.declutterItems = []; - /** * @protected * @type {Array<*>} @@ -274,7 +262,6 @@ class Executor { * @param {import("../../coordinate.js").Coordinate} p4 4th point of the background box. * @param {Array<*>} fillInstruction Fill instruction. * @param {Array<*>} strokeInstruction Stroke instruction. - * @param {boolean} declutter Declutter. */ replayTextBackground_( context, @@ -283,8 +270,7 @@ class Executor { p3, p4, fillInstruction, - strokeInstruction, - declutter + strokeInstruction ) { context.beginPath(); context.moveTo.apply(context, p1); @@ -294,9 +280,6 @@ class Executor { context.lineTo.apply(context, p1); if (fillInstruction) { this.alignFill_ = /** @type {boolean} */ (fillInstruction[2]); - if (declutter) { - context.fillStyle = /** @type {import("../../colorlike.js").ColorLike} */ (fillInstruction[1]); - } this.fill_(context); } if (strokeInstruction) { @@ -317,7 +300,6 @@ class Executor { * @param {import("../canvas.js").Label|HTMLImageElement|HTMLCanvasElement|HTMLVideoElement} imageOrLabel Image. * @param {number} anchorX Anchor X. * @param {number} anchorY Anchor Y. - * @param {import("../canvas.js").DeclutterGroup} declutterGroup Declutter group. * @param {number} height Height. * @param {number} opacity Opacity. * @param {number} originX Origin X. @@ -339,7 +321,6 @@ class Executor { imageOrLabel, anchorX, anchorY, - declutterGroup, height, opacity, originX, @@ -417,15 +398,8 @@ class Executor { tmpExtent ); } - let renderBufferX = 0; - let renderBufferY = 0; - if (declutterGroup) { - const renderBuffer = this.renderBuffer_; - renderBuffer[0] = Math.max(renderBuffer[0], getWidth(tmpExtent)); - renderBufferX = renderBuffer[0]; - renderBuffer[1] = Math.max(renderBuffer[1], getHeight(tmpExtent)); - renderBufferY = renderBuffer[1]; - } + const renderBufferX = 0; // increase this.renderBuffer_ for decluttering + const renderBufferY = 0; // increase this.renderBuffer_ for decluttering const canvas = context.canvas; const strokePadding = strokeInstruction ? (strokeInstruction[2] * scale[0]) / 2 @@ -443,40 +417,7 @@ class Executor { y = Math.round(y); } - if (declutterGroup) { - if (!intersects && declutterGroup[0] == 1) { - return false; - } - const declutterArgs = intersects - ? [ - context, - transform ? transform.slice(0) : null, - opacity, - imageOrLabel, - originX, - originY, - w, - h, - x, - y, - scale, - tmpExtent.slice(), - ] - : null; - if (declutterArgs) { - if (fillStroke) { - declutterArgs.push( - fillInstruction, - strokeInstruction, - p1.slice(0), - p2.slice(0), - p3.slice(0), - p4.slice(0) - ); - } - declutterGroup.push(declutterArgs); - } - } else if (intersects) { + if (intersects) { if (fillStroke) { this.replayTextBackground_( context, @@ -485,8 +426,7 @@ class Executor { p3, p4, /** @type {Array<*>} */ (fillInstruction), - /** @type {Array<*>} */ (strokeInstruction), - false + /** @type {Array<*>} */ (strokeInstruction) ); } drawImageOrLabel( @@ -541,68 +481,6 @@ class Executor { } } - /** - * @param {import("../canvas.js").DeclutterGroup} declutterGroup Declutter group. - * @param {import("../../Feature.js").FeatureLike} feature Feature. - * @param {number} opacity Layer opacity. - * @param {?} declutterTree Declutter tree. - * @return {?} Declutter tree. - */ - renderDeclutter(declutterGroup, feature, opacity, declutterTree) { - /** @type {Array} */ - const boxes = []; - for (let i = 1, ii = declutterGroup.length; i < ii; ++i) { - const declutterData = declutterGroup[i]; - const box = declutterData[11]; - boxes.push({ - minX: box[0], - minY: box[1], - maxX: box[2], - maxY: box[3], - value: feature, - }); - } - if (!declutterTree) { - declutterTree = new RBush(9); - } - let collides = false; - for (let i = 0, ii = boxes.length; i < ii; ++i) { - if (declutterTree.collides(boxes[i])) { - collides = true; - break; - } - } - if (!collides) { - declutterTree.load(boxes); - for (let j = 1, jj = declutterGroup.length; j < jj; ++j) { - const declutterData = /** @type {Array} */ (declutterGroup[j]); - const context = declutterData[0]; - const currentAlpha = context.globalAlpha; - if (currentAlpha !== opacity) { - context.globalAlpha = opacity; - } - if (declutterData.length > 12) { - this.replayTextBackground_( - declutterData[0], - declutterData[14], - declutterData[15], - declutterData[16], - declutterData[17], - declutterData[12], - declutterData[13], - true - ); - } - drawImageOrLabel.apply(undefined, declutterData); - if (currentAlpha !== opacity) { - context.globalAlpha = currentAlpha; - } - } - } - declutterGroup.length = 1; - return declutterTree; - } - /** * @private * @param {string} text The text to draw. @@ -659,7 +537,6 @@ class Executor { featureCallback, opt_hitExtent ) { - this.declutterItems.length = 0; /** @type {Array} */ let pixelCoordinates; if (this.pixelCoordinates_ && equals(transform, this.renderedTransform_)) { @@ -682,17 +559,7 @@ class Executor { const ii = instructions.length; // end of instructions let d = 0; // data index let dd; // end of per-instruction data - let anchorX, - anchorY, - prevX, - prevY, - roundX, - roundY, - declutterGroup, - declutterGroups, - image, - text, - textKey; + let anchorX, anchorY, prevX, prevY, roundX, roundY, image, text, textKey; let strokeKey, fillKey; let pendingFill = 0; let pendingStroke = 0; @@ -796,22 +663,21 @@ class Executor { // Remaining arguments in DRAW_IMAGE are in alphabetical order anchorX = /** @type {number} */ (instruction[4]); anchorY = /** @type {number} */ (instruction[5]); - declutterGroups = featureCallback ? null : instruction[6]; - let height = /** @type {number} */ (instruction[7]); - const opacity = /** @type {number} */ (instruction[8]); - const originX = /** @type {number} */ (instruction[9]); - const originY = /** @type {number} */ (instruction[10]); - const rotateWithView = /** @type {boolean} */ (instruction[11]); - let rotation = /** @type {number} */ (instruction[12]); - const scale = /** @type {import("../../size.js").Size} */ (instruction[13]); - let width = /** @type {number} */ (instruction[14]); + let height = /** @type {number} */ (instruction[6]); + const opacity = /** @type {number} */ (instruction[7]); + const originX = /** @type {number} */ (instruction[8]); + const originY = /** @type {number} */ (instruction[9]); + const rotateWithView = /** @type {boolean} */ (instruction[10]); + let rotation = /** @type {number} */ (instruction[11]); + const scale = /** @type {import("../../size.js").Size} */ (instruction[12]); + let width = /** @type {number} */ (instruction[13]); - if (!image && instruction.length >= 19) { + if (!image && instruction.length >= 18) { // create label images - text = /** @type {string} */ (instruction[18]); - textKey = /** @type {string} */ (instruction[19]); - strokeKey = /** @type {string} */ (instruction[20]); - fillKey = /** @type {string} */ (instruction[21]); + text = /** @type {string} */ (instruction[17]); + textKey = /** @type {string} */ (instruction[18]); + strokeKey = /** @type {string} */ (instruction[19]); + fillKey = /** @type {string} */ (instruction[20]); const labelWithAnchor = this.drawLabelWithPointPlacement_( text, textKey, @@ -820,28 +686,28 @@ class Executor { ); image = labelWithAnchor.label; instruction[3] = image; - const textOffsetX = /** @type {number} */ (instruction[22]); + const textOffsetX = /** @type {number} */ (instruction[21]); anchorX = (labelWithAnchor.anchorX - textOffsetX) * this.pixelRatio; instruction[4] = anchorX; - const textOffsetY = /** @type {number} */ (instruction[23]); + const textOffsetY = /** @type {number} */ (instruction[22]); anchorY = (labelWithAnchor.anchorY - textOffsetY) * this.pixelRatio; instruction[5] = anchorY; height = image.height; - instruction[7] = height; + instruction[6] = height; width = image.width; - instruction[14] = width; + instruction[13] = width; } let geometryWidths; - if (instruction.length > 24) { - geometryWidths = /** @type {number} */ (instruction[24]); + if (instruction.length > 23) { + geometryWidths = /** @type {number} */ (instruction[23]); } let padding, backgroundFill, backgroundStroke; - if (instruction.length > 16) { - padding = /** @type {Array} */ (instruction[15]); - backgroundFill = /** @type {boolean} */ (instruction[16]); - backgroundStroke = /** @type {boolean} */ (instruction[17]); + if (instruction.length > 15) { + padding = /** @type {Array} */ (instruction[14]); + backgroundFill = /** @type {boolean} */ (instruction[15]); + backgroundStroke = /** @type {boolean} */ (instruction[16]); } else { padding = defaultPadding; backgroundFill = false; @@ -856,7 +722,6 @@ class Executor { rotation -= viewRotation; } let widthIndex = 0; - let declutterGroupIndex = 0; for (; d < dd; d += 2) { if ( geometryWidths && @@ -864,14 +729,7 @@ class Executor { ) { continue; } - if (declutterGroups) { - const index = Math.floor(declutterGroupIndex); - declutterGroup = - declutterGroups.length < index + 1 - ? [declutterGroups[0][0]] - : declutterGroups[index]; - } - const rendered = this.replayImageOrLabel_( + this.replayImageOrLabel_( context, contextScale, pixelCoordinates[d], @@ -879,7 +737,6 @@ class Executor { image, anchorX, anchorY, - declutterGroup, height, opacity, originX, @@ -896,19 +753,6 @@ class Executor { ? /** @type {Array<*>} */ (lastStrokeInstruction) : null ); - if ( - rendered && - declutterGroup && - declutterGroups[declutterGroups.length - 1] !== declutterGroup - ) { - declutterGroups.push(declutterGroup); - } - if (declutterGroup) { - if (declutterGroup.length - 1 === declutterGroup[0]) { - this.declutterItems.push(this, declutterGroup, feature); - } - declutterGroupIndex += 1 / declutterGroup[0]; - } } ++i; break; @@ -916,19 +760,18 @@ class Executor { const begin = /** @type {number} */ (instruction[1]); const end = /** @type {number} */ (instruction[2]); const baseline = /** @type {number} */ (instruction[3]); - declutterGroup = featureCallback ? null : instruction[4]; - const overflow = /** @type {number} */ (instruction[5]); - fillKey = /** @type {string} */ (instruction[6]); - const maxAngle = /** @type {number} */ (instruction[7]); - const measurePixelRatio = /** @type {number} */ (instruction[8]); - const offsetY = /** @type {number} */ (instruction[9]); - strokeKey = /** @type {string} */ (instruction[10]); - const strokeWidth = /** @type {number} */ (instruction[11]); - text = /** @type {string} */ (instruction[12]); - textKey = /** @type {string} */ (instruction[13]); + const overflow = /** @type {number} */ (instruction[4]); + fillKey = /** @type {string} */ (instruction[5]); + const maxAngle = /** @type {number} */ (instruction[6]); + const measurePixelRatio = /** @type {number} */ (instruction[7]); + const offsetY = /** @type {number} */ (instruction[8]); + strokeKey = /** @type {string} */ (instruction[9]); + const strokeWidth = /** @type {number} */ (instruction[10]); + text = /** @type {string} */ (instruction[11]); + textKey = /** @type {string} */ (instruction[12]); const pixelRatioScale = [ - /** @type {number} */ (instruction[14]), - /** @type {number} */ (instruction[14]), + /** @type {number} */ (instruction[13]), + /** @type {number} */ (instruction[13]), ]; const textState = this.textStates[textKey]; @@ -990,7 +833,6 @@ class Executor { label, anchorX, anchorY, - declutterGroup, label.height, 1, 0, @@ -1021,7 +863,6 @@ class Executor { label, anchorX, anchorY, - declutterGroup, label.height, 1, 0, @@ -1036,9 +877,6 @@ class Executor { ) || rendered; } } - if (rendered) { - this.declutterItems.push(this, declutterGroup, feature); - } } } ++i; diff --git a/src/ol/render/canvas/ExecutorGroup.js b/src/ol/render/canvas/ExecutorGroup.js index a14d6bc8a7..427d17b4a5 100644 --- a/src/ol/render/canvas/ExecutorGroup.js +++ b/src/ol/render/canvas/ExecutorGroup.js @@ -162,7 +162,6 @@ class ExecutorGroup { * @param {number} rotation Rotation. * @param {number} hitTolerance Hit tolerance in pixels. * @param {function(import("../../Feature.js").FeatureLike): T} callback Feature callback. - * @param {Array} declutteredFeatures Decluttered features. * @return {T|undefined} Callback result. * @template T */ @@ -171,8 +170,7 @@ class ExecutorGroup { resolution, rotation, hitTolerance, - callback, - declutteredFeatures + callback ) { hitTolerance = Math.round(hitTolerance); const contextSize = hitTolerance * 2 + 1; @@ -234,17 +232,7 @@ class ExecutorGroup { for (let j = 0; j < contextSize; j++) { if (mask[i][j]) { if (imageData[(j * contextSize + i) * 4 + 3] > 0) { - let result; - if ( - !( - declutteredFeatures && - (builderType == BuilderType.IMAGE || - builderType == BuilderType.TEXT) - ) || - declutteredFeatures.indexOf(feature) !== -1 - ) { - result = callback(feature); - } + const result = callback(feature); if (result) { return result; } else { @@ -318,7 +306,6 @@ class ExecutorGroup { * @param {boolean} snapToPixel Snap point symbols and test to integer pixel. * @param {Array=} opt_builderTypes Ordered replay types to replay. * Default is {@link module:ol/render/replay~ORDER} - * @param {Object=} opt_declutterReplays Declutter replays. */ execute( context, @@ -326,8 +313,7 @@ class ExecutorGroup { transform, viewRotation, snapToPixel, - opt_builderTypes, - opt_declutterReplays + opt_builderTypes ) { /** @type {Array} */ const zs = Object.keys(this.executorsByZIndex_).map(Number); @@ -349,26 +335,13 @@ class ExecutorGroup { const builderType = builderTypes[j]; replay = replays[builderType]; if (replay !== undefined) { - if ( - opt_declutterReplays && - (builderType == BuilderType.IMAGE || - builderType == BuilderType.TEXT) - ) { - const declutter = opt_declutterReplays[zIndexKey]; - if (!declutter) { - opt_declutterReplays[zIndexKey] = [replay, transform.slice(0)]; - } else { - declutter.push(replay, transform.slice(0)); - } - } else { - replay.execute( - context, - contextScale, - transform, - viewRotation, - snapToPixel - ); - } + replay.execute( + context, + contextScale, + transform, + viewRotation, + snapToPixel + ); } } } @@ -454,41 +427,4 @@ export function getCircleArray(radius) { return arr; } -/** - * @param {!Object>} declutterReplays Declutter replays. - * @param {CanvasRenderingContext2D} context Context. - * @param {number} rotation Rotation. - * @param {number} opacity Opacity. - * @param {boolean} snapToPixel Snap point symbols and text to integer pixels. - * @param {Array} declutterItems Declutter items. - */ -export function replayDeclutter( - declutterReplays, - context, - rotation, - opacity, - snapToPixel, - declutterItems -) { - const zs = Object.keys(declutterReplays) - .map(Number) - .sort(numberSafeCompareFunction); - for (let z = 0, zz = zs.length; z < zz; ++z) { - const executorData = declutterReplays[zs[z].toString()]; - let currentExecutor; - for (let i = 0, ii = executorData.length; i < ii; ) { - const executor = executorData[i++]; - const transform = executorData[i++]; - executor.execute(context, 1, transform, rotation, snapToPixel); - if (executor !== currentExecutor && executor.declutterItems.length > 0) { - currentExecutor = executor; - declutterItems.push({ - items: executor.declutterItems, - opacity: opacity, - }); - } - } - } -} - export default ExecutorGroup; diff --git a/src/ol/render/canvas/ImageBuilder.js b/src/ol/render/canvas/ImageBuilder.js index e50f2c88a7..28ad1e10ee 100644 --- a/src/ol/render/canvas/ImageBuilder.js +++ b/src/ol/render/canvas/ImageBuilder.js @@ -14,12 +14,6 @@ class CanvasImageBuilder extends CanvasBuilder { constructor(tolerance, maxExtent, resolution, pixelRatio) { super(tolerance, maxExtent, resolution, pixelRatio); - /** - * @private - * @type {import("../canvas.js").DeclutterGroups} - */ - this.declutterGroups_ = null; - /** * @private * @type {HTMLCanvasElement|HTMLVideoElement|HTMLImageElement} @@ -120,7 +114,6 @@ class CanvasImageBuilder extends CanvasBuilder { // Remaining arguments to DRAW_IMAGE are in alphabetical order this.anchorX_ * this.imagePixelRatio_, this.anchorY_ * this.imagePixelRatio_, - this.declutterGroups_, Math.ceil(this.height_ * this.imagePixelRatio_), this.opacity_, this.originX_, @@ -141,7 +134,6 @@ class CanvasImageBuilder extends CanvasBuilder { // Remaining arguments to DRAW_IMAGE are in alphabetical order this.anchorX_, this.anchorY_, - this.declutterGroups_, this.height_, this.opacity_, this.originX_, @@ -175,7 +167,6 @@ class CanvasImageBuilder extends CanvasBuilder { // Remaining arguments to DRAW_IMAGE are in alphabetical order this.anchorX_ * this.imagePixelRatio_, this.anchorY_ * this.imagePixelRatio_, - this.declutterGroups_, Math.ceil(this.height_ * this.imagePixelRatio_), this.opacity_, this.originX_, @@ -196,7 +187,6 @@ class CanvasImageBuilder extends CanvasBuilder { // Remaining arguments to DRAW_IMAGE are in alphabetical order this.anchorX_, this.anchorY_, - this.declutterGroups_, this.height_, this.opacity_, this.originX_, @@ -233,9 +223,8 @@ class CanvasImageBuilder extends CanvasBuilder { /** * @param {import("../../style/Image.js").default} imageStyle Image style. - * @param {import("../canvas.js").DeclutterGroup} declutterGroups Declutter. */ - setImageStyle(imageStyle, declutterGroups) { + setImageStyle(imageStyle) { const anchor = imageStyle.getAnchor(); const size = imageStyle.getSize(); const hitDetectionImage = imageStyle.getHitDetectionImage(); @@ -244,7 +233,6 @@ class CanvasImageBuilder extends CanvasBuilder { this.imagePixelRatio_ = imageStyle.getPixelRatio(this.pixelRatio); this.anchorX_ = anchor[0]; this.anchorY_ = anchor[1]; - this.declutterGroups_ = declutterGroups; this.hitDetectionImage_ = hitDetectionImage; this.image_ = image; this.height_ = size[1]; diff --git a/src/ol/render/canvas/TextBuilder.js b/src/ol/render/canvas/TextBuilder.js index a5235a2a61..903d6dcee3 100644 --- a/src/ol/render/canvas/TextBuilder.js +++ b/src/ol/render/canvas/TextBuilder.js @@ -52,12 +52,6 @@ class CanvasTextBuilder extends CanvasBuilder { constructor(tolerance, maxExtent, resolution, pixelRatio) { super(tolerance, maxExtent, resolution, pixelRatio); - /** - * @private - * @type {import("../canvas.js").DeclutterGroups} - */ - this.declutterGroups_; - /** * @private * @type {Array} @@ -226,12 +220,7 @@ class CanvasTextBuilder extends CanvasBuilder { } const end = coordinates.length; flatOffset = ends[o]; - const declutterGroup = this.declutterGroups_ - ? o === 0 - ? this.declutterGroups_[0] - : [].concat(this.declutterGroups_[0]) - : null; - this.drawChars_(begin, end, declutterGroup); + this.drawChars_(begin, end); begin = end; } this.endGeometry(feature); @@ -331,7 +320,6 @@ class CanvasTextBuilder extends CanvasBuilder { null, NaN, NaN, - this.declutterGroups_, NaN, 1, 0, @@ -363,7 +351,6 @@ class CanvasTextBuilder extends CanvasBuilder { null, NaN, NaN, - this.declutterGroups_, NaN, 1, 0, @@ -433,9 +420,8 @@ class CanvasTextBuilder extends CanvasBuilder { * @private * @param {number} begin Begin. * @param {number} end End. - * @param {import("../canvas.js").DeclutterGroup} declutterGroup Declutter group. */ - drawChars_(begin, end, declutterGroup) { + drawChars_(begin, end) { const strokeState = this.textStrokeState_; const textState = this.textState_; @@ -458,7 +444,6 @@ class CanvasTextBuilder extends CanvasBuilder { begin, end, baseline, - declutterGroup, textState.overflow, fillKey, textState.maxAngle, @@ -475,7 +460,6 @@ class CanvasTextBuilder extends CanvasBuilder { begin, end, baseline, - declutterGroup, textState.overflow, fillKey, textState.maxAngle, @@ -491,15 +475,12 @@ class CanvasTextBuilder extends CanvasBuilder { /** * @param {import("../../style/Text.js").default} textStyle Text style. - * @param {import("../canvas.js").DeclutterGroups} declutterGroups Declutter. */ - setTextStyle(textStyle, declutterGroups) { + setTextStyle(textStyle) { let textState, fillState, strokeState; if (!textStyle) { this.text_ = ''; } else { - this.declutterGroups_ = declutterGroups; - const textFillStyle = textStyle.getFill(); if (!textFillStyle) { fillState = null; diff --git a/src/ol/renderer/Layer.js b/src/ol/renderer/Layer.js index b814c60b64..c6efd2711a 100644 --- a/src/ol/renderer/Layer.js +++ b/src/ol/renderer/Layer.js @@ -101,17 +101,10 @@ class LayerRenderer extends Observable { * @param {import("../PluggableMap.js").FrameState} frameState Frame state. * @param {number} hitTolerance Hit tolerance in pixels. * @param {function(import("../Feature.js").FeatureLike, import("../layer/Layer.js").default): T} callback Feature callback. - * @param {Array} declutteredFeatures Decluttered features. * @return {T|void} Callback result. * @template T */ - forEachFeatureAtCoordinate( - coordinate, - frameState, - hitTolerance, - callback, - declutteredFeatures - ) {} + forEachFeatureAtCoordinate(coordinate, frameState, hitTolerance, callback) {} /** * @abstract diff --git a/src/ol/renderer/Map.js b/src/ol/renderer/Map.js index d6f185459d..8ad03b14ca 100644 --- a/src/ol/renderer/Map.js +++ b/src/ol/renderer/Map.js @@ -8,7 +8,6 @@ import {compose as composeTransform, makeInverse} from '../transform.js'; import {getWidth} from '../extent.js'; import {shared as iconImageCache} from '../style/IconImageCache.js'; import {inView} from '../layer/Layer.js'; -import {renderDeclutterItems} from '../render.js'; import {wrapX} from '../coordinate.js'; /** @@ -26,11 +25,6 @@ class MapRenderer extends Disposable { * @type {import("../PluggableMap.js").default} */ this.map_ = map; - - /** - * @private - */ - this.declutterTree_ = null; } /** @@ -116,12 +110,6 @@ class MapRenderer extends Disposable { const layerStates = frameState.layerStatesArray; const numLayers = layerStates.length; - let declutteredFeatures; - if (this.declutterTree_) { - declutteredFeatures = this.declutterTree_.all().map(function (entry) { - return entry.value; - }); - } const tmpCoord = []; for (let i = 0; i < offsets.length; i++) { @@ -149,8 +137,7 @@ class MapRenderer extends Disposable { tmpCoord, frameState, hitTolerance, - callback, - declutteredFeatures + callback ); } if (result) { @@ -226,9 +213,7 @@ class MapRenderer extends Disposable { * Render. * @param {?import("../PluggableMap.js").FrameState} frameState Frame state. */ - renderFrame(frameState) { - this.declutterTree_ = renderDeclutterItems(frameState, this.declutterTree_); - } + renderFrame(frameState) {} /** * @param {import("../PluggableMap.js").FrameState} frameState Frame state. diff --git a/src/ol/renderer/canvas/VectorImageLayer.js b/src/ol/renderer/canvas/VectorImageLayer.js index 76ec2f8e0f..5bc4f0540f 100644 --- a/src/ol/renderer/canvas/VectorImageLayer.js +++ b/src/ol/renderer/canvas/VectorImageLayer.js @@ -10,7 +10,6 @@ import ViewHint from '../../ViewHint.js'; import {apply, compose, create} from '../../transform.js'; import {assign} from '../../obj.js'; import {getHeight, getWidth, isEmpty, scaleFromCenter} from '../../extent.js'; -import {renderDeclutterItems} from '../../render.js'; /** * @classdesc @@ -115,7 +114,6 @@ class CanvasVectorImageLayerRenderer extends CanvasImageLayerRenderer { {}, frameState, { - declutterItems: [], extent: renderedExtent, size: [width, height], viewState: /** @type {import("../../View.js").State} */ (assign( @@ -139,7 +137,6 @@ class CanvasVectorImageLayerRenderer extends CanvasImageLayerRenderer { ) { vectorRenderer.clipping = false; vectorRenderer.renderFrame(imageFrameState, null); - renderDeclutterItems(imageFrameState, null); callback(); } } @@ -191,32 +188,23 @@ class CanvasVectorImageLayerRenderer extends CanvasImageLayerRenderer { * @param {import("../../PluggableMap.js").FrameState} frameState Frame state. * @param {number} hitTolerance Hit tolerance in pixels. * @param {function(import("../../Feature.js").FeatureLike, import("../../layer/Layer.js").default): T} callback Feature callback. - * @param {Array} declutteredFeatures Decluttered features. * @return {T|void} Callback result. * @template T */ - forEachFeatureAtCoordinate( - coordinate, - frameState, - hitTolerance, - callback, - declutteredFeatures - ) { + forEachFeatureAtCoordinate(coordinate, frameState, hitTolerance, callback) { if (this.vectorRenderer_) { return this.vectorRenderer_.forEachFeatureAtCoordinate( coordinate, frameState, hitTolerance, - callback, - declutteredFeatures + callback ); } else { return super.forEachFeatureAtCoordinate( coordinate, frameState, hitTolerance, - callback, - declutteredFeatures + callback ); } } diff --git a/src/ol/renderer/canvas/VectorLayer.js b/src/ol/renderer/canvas/VectorLayer.js index 3bde6ce1ce..4527c4c5d0 100644 --- a/src/ol/renderer/canvas/VectorLayer.js +++ b/src/ol/renderer/canvas/VectorLayer.js @@ -3,9 +3,7 @@ */ import CanvasBuilderGroup from '../../render/canvas/BuilderGroup.js'; import CanvasLayerRenderer from './Layer.js'; -import ExecutorGroup, { - replayDeclutter, -} from '../../render/canvas/ExecutorGroup.js'; +import ExecutorGroup from '../../render/canvas/ExecutorGroup.js'; import ViewHint from '../../ViewHint.js'; import { apply, @@ -219,8 +217,6 @@ class CanvasVectorLayerRenderer extends CanvasLayerRenderer { viewHints[ViewHint.ANIMATING] || viewHints[ViewHint.INTERACTING] ); - const declutterReplays = this.getLayer().getDeclutter() ? {} : null; - const multiWorld = vectorSource.getWrapX() && projection.canWrapX(); const worldWidth = multiWorld ? getWidth(projectionExtent) : null; const endWorld = multiWorld @@ -245,26 +241,10 @@ class CanvasVectorLayerRenderer extends CanvasLayerRenderer { transform, rotation, snapToPixel, - undefined, - declutterReplays + undefined ); } while (++world < endWorld); - if (declutterReplays) { - const viewHints = frameState.viewHints; - const hifi = !( - viewHints[ViewHint.ANIMATING] || viewHints[ViewHint.INTERACTING] - ); - replayDeclutter( - declutterReplays, - context, - rotation, - 1, - hifi, - frameState.declutterItems - ); - } - if (clipped) { context.restore(); } @@ -388,17 +368,10 @@ class CanvasVectorLayerRenderer extends CanvasLayerRenderer { * @param {import("../../PluggableMap.js").FrameState} frameState Frame state. * @param {number} hitTolerance Hit tolerance in pixels. * @param {function(import("../../Feature.js").FeatureLike, import("../../layer/Layer.js").default): T} callback Feature callback. - * @param {Array} declutteredFeatures Decluttered features. * @return {T|void} Callback result. * @template T */ - forEachFeatureAtCoordinate( - coordinate, - frameState, - hitTolerance, - callback, - declutteredFeatures - ) { + forEachFeatureAtCoordinate(coordinate, frameState, hitTolerance, callback) { if (!this.replayGroup_) { return undefined; } else { @@ -423,8 +396,7 @@ class CanvasVectorLayerRenderer extends CanvasLayerRenderer { features[key] = true; return callback(feature, layer); } - }, - layer.getDeclutter() ? declutteredFeatures : null + } ); return result; @@ -556,8 +528,7 @@ class CanvasVectorLayerRenderer extends CanvasLayerRenderer { getRenderTolerance(resolution, pixelRatio), extent, resolution, - pixelRatio, - vectorLayer.getDeclutter() + pixelRatio ); const userProjection = getUserProjection(); diff --git a/src/ol/renderer/canvas/VectorTileLayer.js b/src/ol/renderer/canvas/VectorTileLayer.js index efb3763063..f17e3cfb64 100644 --- a/src/ol/renderer/canvas/VectorTileLayer.js +++ b/src/ol/renderer/canvas/VectorTileLayer.js @@ -2,9 +2,7 @@ * @module ol/renderer/canvas/VectorTileLayer */ import CanvasBuilderGroup from '../../render/canvas/BuilderGroup.js'; -import CanvasExecutorGroup, { - replayDeclutter, -} from '../../render/canvas/ExecutorGroup.js'; +import CanvasExecutorGroup from '../../render/canvas/ExecutorGroup.js'; import CanvasTileLayerRenderer from './TileLayer.js'; import EventType from '../../events/EventType.js'; import ReplayType from '../../render/canvas/BuilderType.js'; @@ -292,8 +290,7 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer { 0, sharedExtent, resolution, - pixelRatio, - layer.getDeclutter() + pixelRatio ); const squaredTolerance = getSquaredRenderTolerance( resolution, @@ -365,17 +362,10 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer { * @param {import("../../PluggableMap.js").FrameState} frameState Frame state. * @param {number} hitTolerance Hit tolerance in pixels. * @param {function(import("../../Feature.js").FeatureLike, import("../../layer/Layer.js").default): T} callback Feature callback. - * @param {Array} declutteredFeatures Decluttered features. * @return {T|void} Callback result. * @template T */ - forEachFeatureAtCoordinate( - coordinate, - frameState, - hitTolerance, - callback, - declutteredFeatures - ) { + forEachFeatureAtCoordinate(coordinate, frameState, hitTolerance, callback) { const resolution = frameState.viewState.resolution; const rotation = frameState.viewState.rotation; hitTolerance = hitTolerance == undefined ? 0 : hitTolerance; @@ -420,11 +410,7 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer { * @return {?} Callback result. */ function (feature) { - if ( - tileContainsCoordinate || - (declutteredFeatures && - declutteredFeatures.indexOf(feature) !== -1) - ) { + if (tileContainsCoordinate) { let key = feature.getId(); if (key === undefined) { key = getUid(feature); @@ -434,8 +420,7 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer { return callback(feature, layer); } } - }, - layer.getDeclutter() ? declutteredFeatures : null + } ); } } @@ -587,7 +572,6 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer { } const context = this.context; - const declutterReplays = layer.getDeclutter() ? {} : null; const replayTypes = VECTOR_REPLAYS[renderMode]; const pixelRatio = frameState.pixelRatio; const viewState = frameState.viewState; @@ -640,27 +624,29 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer { } const currentZ = tile.tileCoord[0]; let currentClip; - if (!declutterReplays && !clipped) { + if (!clipped) { currentClip = executorGroup.getClipCoords(transform); - context.save(); + if (currentClip) { + context.save(); - // Create a clip mask for regions in this low resolution tile that are - // already filled by a higher resolution tile - for (let j = 0, jj = clips.length; j < jj; ++j) { - const clip = clips[j]; - if (currentZ < clipZs[j]) { - context.beginPath(); - // counter-clockwise (outer ring) for current tile - context.moveTo(currentClip[0], currentClip[1]); - context.lineTo(currentClip[2], currentClip[3]); - context.lineTo(currentClip[4], currentClip[5]); - context.lineTo(currentClip[6], currentClip[7]); - // clockwise (inner ring) for higher resolution tile - context.moveTo(clip[6], clip[7]); - context.lineTo(clip[4], clip[5]); - context.lineTo(clip[2], clip[3]); - context.lineTo(clip[0], clip[1]); - context.clip(); + // Create a clip mask for regions in this low resolution tile that are + // already filled by a higher resolution tile + for (let j = 0, jj = clips.length; j < jj; ++j) { + const clip = clips[j]; + if (currentZ < clipZs[j]) { + context.beginPath(); + // counter-clockwise (outer ring) for current tile + context.moveTo(currentClip[0], currentClip[1]); + context.lineTo(currentClip[2], currentClip[3]); + context.lineTo(currentClip[4], currentClip[5]); + context.lineTo(currentClip[6], currentClip[7]); + // clockwise (inner ring) for higher resolution tile + context.moveTo(clip[6], clip[7]); + context.lineTo(clip[4], clip[5]); + context.lineTo(clip[2], clip[3]); + context.lineTo(clip[0], clip[1]); + context.clip(); + } } } } @@ -670,10 +656,9 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer { transform, rotation, hifi, - replayTypes, - declutterReplays + replayTypes ); - if (!declutterReplays && !clipped) { + if (!clipped && currentClip) { context.restore(); clips.push(currentClip); clipZs.push(currentZ); @@ -681,17 +666,6 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer { } } } - if (declutterReplays) { - const layerState = frameState.layerStatesArray[frameState.layerIndex]; - replayDeclutter( - declutterReplays, - context, - rotation, - layerState.opacity, - hifi, - frameState.declutterItems - ); - } return this.container; } diff --git a/src/ol/renderer/vector.js b/src/ol/renderer/vector.js index 579f15960f..b293c53f9f 100644 --- a/src/ol/renderer/vector.js +++ b/src/ol/renderer/vector.js @@ -80,7 +80,7 @@ function renderCircleGeometry(builderGroup, geometry, style, feature) { style.getZIndex(), BuilderType.TEXT ); - textReplay.setTextStyle(textStyle, builderGroup.addDeclutter(false)); + textReplay.setTextStyle(textStyle); textReplay.drawText(geometry, feature); } } @@ -224,7 +224,7 @@ function renderLineStringGeometry(builderGroup, geometry, style, feature) { style.getZIndex(), BuilderType.TEXT ); - textReplay.setTextStyle(textStyle, builderGroup.addDeclutter(false)); + textReplay.setTextStyle(textStyle); textReplay.drawText(geometry, feature); } } @@ -251,7 +251,7 @@ function renderMultiLineStringGeometry(builderGroup, geometry, style, feature) { style.getZIndex(), BuilderType.TEXT ); - textReplay.setTextStyle(textStyle, builderGroup.addDeclutter(false)); + textReplay.setTextStyle(textStyle); textReplay.drawText(geometry, feature); } } @@ -279,7 +279,7 @@ function renderMultiPolygonGeometry(builderGroup, geometry, style, feature) { style.getZIndex(), BuilderType.TEXT ); - textReplay.setTextStyle(textStyle, builderGroup.addDeclutter(false)); + textReplay.setTextStyle(textStyle); textReplay.drawText(geometry, feature); } } @@ -300,7 +300,7 @@ function renderPointGeometry(builderGroup, geometry, style, feature) { style.getZIndex(), BuilderType.IMAGE ); - imageReplay.setImageStyle(imageStyle, builderGroup.addDeclutter(false)); + imageReplay.setImageStyle(imageStyle); imageReplay.drawPoint(geometry, feature); } const textStyle = style.getText(); @@ -309,7 +309,7 @@ function renderPointGeometry(builderGroup, geometry, style, feature) { style.getZIndex(), BuilderType.TEXT ); - textReplay.setTextStyle(textStyle, builderGroup.addDeclutter(!!imageStyle)); + textReplay.setTextStyle(textStyle); textReplay.drawText(geometry, feature); } } @@ -330,7 +330,7 @@ function renderMultiPointGeometry(builderGroup, geometry, style, feature) { style.getZIndex(), BuilderType.IMAGE ); - imageReplay.setImageStyle(imageStyle, builderGroup.addDeclutter(false)); + imageReplay.setImageStyle(imageStyle); imageReplay.drawMultiPoint(geometry, feature); } const textStyle = style.getText(); @@ -339,7 +339,7 @@ function renderMultiPointGeometry(builderGroup, geometry, style, feature) { style.getZIndex(), BuilderType.TEXT ); - textReplay.setTextStyle(textStyle, builderGroup.addDeclutter(!!imageStyle)); + textReplay.setTextStyle(textStyle); textReplay.drawText(geometry, feature); } } @@ -367,7 +367,7 @@ function renderPolygonGeometry(builderGroup, geometry, style, feature) { style.getZIndex(), BuilderType.TEXT ); - textReplay.setTextStyle(textStyle, builderGroup.addDeclutter(false)); + textReplay.setTextStyle(textStyle); textReplay.drawText(geometry, feature); } } diff --git a/src/ol/renderer/webgl/PointsLayer.js b/src/ol/renderer/webgl/PointsLayer.js index a506d8dd5b..5305da78d9 100644 --- a/src/ol/renderer/webgl/PointsLayer.js +++ b/src/ol/renderer/webgl/PointsLayer.js @@ -598,17 +598,10 @@ class WebGLPointsLayerRenderer extends WebGLLayerRenderer { * @param {import("../../PluggableMap.js").FrameState} frameState Frame state. * @param {number} hitTolerance Hit tolerance in pixels. * @param {function(import("../../Feature.js").FeatureLike, import("../../layer/Layer.js").default): T} callback Feature callback. - * @param {Array} declutteredFeatures Decluttered features. * @return {T|void} Callback result. * @template T */ - forEachFeatureAtCoordinate( - coordinate, - frameState, - hitTolerance, - callback, - declutteredFeatures - ) { + forEachFeatureAtCoordinate(coordinate, frameState, hitTolerance, callback) { assert(this.hitDetectionEnabled_, 66); if (!this.hitRenderInstructions_) { return; diff --git a/src/ol/source/Raster.js b/src/ol/source/Raster.js index fb61fc6ed1..abdbd161cb 100644 --- a/src/ol/source/Raster.js +++ b/src/ol/source/Raster.js @@ -565,7 +565,6 @@ class RasterSource extends ImageSource { }), viewHints: [], wantedTiles: {}, - declutterItems: [], }; this.setAttributions(function (frameState) {