No empty declutter instructions, but with individual box
This commit is contained in:
@@ -7,7 +7,6 @@ import ImageBuilder from './ImageBuilder.js';
|
|||||||
import LineStringBuilder from './LineStringBuilder.js';
|
import LineStringBuilder from './LineStringBuilder.js';
|
||||||
import PolygonBuilder from './PolygonBuilder.js';
|
import PolygonBuilder from './PolygonBuilder.js';
|
||||||
import TextBuilder from './TextBuilder.js';
|
import TextBuilder from './TextBuilder.js';
|
||||||
import {createEmpty} from '../../extent.js';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {Object<import("./BuilderType").default, typeof Builder>}
|
* @type {Object<import("./BuilderType").default, typeof Builder>}
|
||||||
@@ -78,15 +77,15 @@ class BuilderGroup {
|
|||||||
* @return {import("../canvas").DeclutterGroups} The resulting instruction groups.
|
* @return {import("../canvas").DeclutterGroups} The resulting instruction groups.
|
||||||
*/
|
*/
|
||||||
addDeclutter(group) {
|
addDeclutter(group) {
|
||||||
|
/** @type {Array<*>} */
|
||||||
let declutter = null;
|
let declutter = null;
|
||||||
if (this.declutter_) {
|
if (this.declutter_) {
|
||||||
if (group) {
|
if (group) {
|
||||||
declutter = this.declutterGroups_;
|
declutter = this.declutterGroups_;
|
||||||
/** @type {number} */ (declutter[0][4])++;
|
/** @type {number} */ (declutter[0][0])++;
|
||||||
} else {
|
} else {
|
||||||
declutter = [createEmpty()];
|
declutter = [[1]];
|
||||||
this.declutterGroups_ = declutter;
|
this.declutterGroups_ = declutter;
|
||||||
declutter[0].push(1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return declutter;
|
return declutter;
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ import {
|
|||||||
import {
|
import {
|
||||||
createEmpty,
|
createEmpty,
|
||||||
createOrUpdate,
|
createOrUpdate,
|
||||||
createOrUpdateEmpty,
|
getHeight,
|
||||||
extend,
|
getWidth,
|
||||||
intersects,
|
intersects,
|
||||||
} from '../../extent.js';
|
} from '../../extent.js';
|
||||||
import {
|
import {
|
||||||
@@ -323,6 +323,7 @@ class Executor {
|
|||||||
* @param {Array<number>} padding Padding.
|
* @param {Array<number>} padding Padding.
|
||||||
* @param {Array<*>} fillInstruction Fill instruction.
|
* @param {Array<*>} fillInstruction Fill instruction.
|
||||||
* @param {Array<*>} strokeInstruction Stroke instruction.
|
* @param {Array<*>} strokeInstruction Stroke instruction.
|
||||||
|
* @return {boolean} The image or label was rendered.
|
||||||
*/
|
*/
|
||||||
replayImageOrLabel_(
|
replayImageOrLabel_(
|
||||||
context,
|
context,
|
||||||
@@ -431,10 +432,9 @@ class Executor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (declutterGroup) {
|
if (declutterGroup) {
|
||||||
if (!intersects && declutterGroup[4] == 1) {
|
if (!intersects && declutterGroup[0] == 1) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
extend(declutterGroup, tmpExtent);
|
|
||||||
const declutterArgs = intersects
|
const declutterArgs = intersects
|
||||||
? [
|
? [
|
||||||
context,
|
context,
|
||||||
@@ -448,6 +448,7 @@ class Executor {
|
|||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
scale,
|
scale,
|
||||||
|
tmpExtent.slice(),
|
||||||
]
|
]
|
||||||
: null;
|
: null;
|
||||||
if (declutterArgs) {
|
if (declutterArgs) {
|
||||||
@@ -490,6 +491,7 @@ class Executor {
|
|||||||
scale
|
scale
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -535,51 +537,57 @@ class Executor {
|
|||||||
* @return {?} Declutter tree.
|
* @return {?} Declutter tree.
|
||||||
*/
|
*/
|
||||||
renderDeclutter(declutterGroup, feature, opacity, declutterTree) {
|
renderDeclutter(declutterGroup, feature, opacity, declutterTree) {
|
||||||
if (declutterGroup && declutterGroup.length > 5) {
|
/** @type {Array<import("../../structs/RBush.js").Entry>} */
|
||||||
const groupCount = declutterGroup[4];
|
const boxes = [];
|
||||||
if (groupCount == 1 || groupCount == declutterGroup.length - 5) {
|
for (let i = 1, ii = declutterGroup.length; i < ii; ++i) {
|
||||||
/** @type {import("../../structs/RBush.js").Entry} */
|
const declutterData = declutterGroup[i];
|
||||||
const box = {
|
const box = declutterData[11];
|
||||||
minX: /** @type {number} */ (declutterGroup[0]),
|
boxes.push({
|
||||||
minY: /** @type {number} */ (declutterGroup[1]),
|
minX: box[0],
|
||||||
maxX: /** @type {number} */ (declutterGroup[2]),
|
minY: box[1],
|
||||||
maxY: /** @type {number} */ (declutterGroup[3]),
|
maxX: box[2],
|
||||||
value: feature,
|
maxY: box[3],
|
||||||
};
|
value: feature,
|
||||||
if (!declutterTree) {
|
});
|
||||||
declutterTree = new RBush(9);
|
}
|
||||||
}
|
if (!declutterTree) {
|
||||||
if (!declutterTree.collides(box)) {
|
declutterTree = new RBush(9);
|
||||||
declutterTree.insert(box);
|
}
|
||||||
for (let j = 5, jj = declutterGroup.length; j < jj; ++j) {
|
let collides = false;
|
||||||
const declutterData = /** @type {Array} */ (declutterGroup[j]);
|
for (let i = 0, ii = boxes.length; i < ii; ++i) {
|
||||||
const context = declutterData[0];
|
if (declutterTree.collides(boxes[i])) {
|
||||||
const currentAlpha = context.globalAlpha;
|
collides = true;
|
||||||
if (currentAlpha !== opacity) {
|
break;
|
||||||
context.globalAlpha = opacity;
|
|
||||||
}
|
|
||||||
if (declutterData.length > 11) {
|
|
||||||
this.replayTextBackground_(
|
|
||||||
declutterData[0],
|
|
||||||
declutterData[13],
|
|
||||||
declutterData[14],
|
|
||||||
declutterData[15],
|
|
||||||
declutterData[16],
|
|
||||||
declutterData[11],
|
|
||||||
declutterData[12],
|
|
||||||
true
|
|
||||||
);
|
|
||||||
}
|
|
||||||
drawImageOrLabel.apply(undefined, declutterData);
|
|
||||||
if (currentAlpha !== opacity) {
|
|
||||||
context.globalAlpha = currentAlpha;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
declutterGroup.length = 5;
|
|
||||||
createOrUpdateEmpty(declutterGroup);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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;
|
return declutterTree;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -847,13 +855,11 @@ class Executor {
|
|||||||
if (declutterGroups) {
|
if (declutterGroups) {
|
||||||
const index = Math.floor(declutterGroupIndex);
|
const index = Math.floor(declutterGroupIndex);
|
||||||
if (declutterGroups.length < index + 1) {
|
if (declutterGroups.length < index + 1) {
|
||||||
declutterGroup = createEmpty();
|
declutterGroup = [declutterGroups[0][0], declutterGroups[0][1]];
|
||||||
declutterGroup.push(declutterGroups[0][4]);
|
|
||||||
declutterGroups.push(declutterGroup);
|
|
||||||
}
|
}
|
||||||
declutterGroup = declutterGroups[index];
|
declutterGroup = declutterGroups[index];
|
||||||
}
|
}
|
||||||
this.replayImageOrLabel_(
|
const rendered = this.replayImageOrLabel_(
|
||||||
context,
|
context,
|
||||||
contextScale,
|
contextScale,
|
||||||
pixelCoordinates[d],
|
pixelCoordinates[d],
|
||||||
@@ -878,12 +884,17 @@ class Executor {
|
|||||||
? /** @type {Array<*>} */ (lastStrokeInstruction)
|
? /** @type {Array<*>} */ (lastStrokeInstruction)
|
||||||
: null
|
: null
|
||||||
);
|
);
|
||||||
if (declutterGroup) {
|
if (
|
||||||
if (declutterGroupIndex === Math.floor(declutterGroupIndex)) {
|
rendered &&
|
||||||
this.declutterItems.push(this, declutterGroup, feature);
|
declutterGroup &&
|
||||||
}
|
declutterGroups[declutterGroups.length] !== declutterGroup
|
||||||
declutterGroupIndex += 1 / declutterGroup[4];
|
) {
|
||||||
|
declutterGroups.push(declutterGroup);
|
||||||
}
|
}
|
||||||
|
if (declutterGroup.length - 1 === declutterGroup[0]) {
|
||||||
|
this.declutterItems.push(this, declutterGroup, feature);
|
||||||
|
}
|
||||||
|
declutterGroupIndex += 1 / declutterGroup[0];
|
||||||
}
|
}
|
||||||
++i;
|
++i;
|
||||||
break;
|
break;
|
||||||
@@ -935,6 +946,7 @@ class Executor {
|
|||||||
cachedWidths
|
cachedWidths
|
||||||
);
|
);
|
||||||
if (parts) {
|
if (parts) {
|
||||||
|
let rendered = false;
|
||||||
let c, cc, chars, label, part;
|
let c, cc, chars, label, part;
|
||||||
if (strokeKey) {
|
if (strokeKey) {
|
||||||
for (c = 0, cc = parts.length; c < cc; ++c) {
|
for (c = 0, cc = parts.length; c < cc; ++c) {
|
||||||
@@ -946,27 +958,28 @@ class Executor {
|
|||||||
baseline * label.height +
|
baseline * label.height +
|
||||||
(0.5 - baseline) * 2 * strokeWidth -
|
(0.5 - baseline) * 2 * strokeWidth -
|
||||||
offsetY;
|
offsetY;
|
||||||
this.replayImageOrLabel_(
|
rendered =
|
||||||
context,
|
this.replayImageOrLabel_(
|
||||||
contextScale,
|
context,
|
||||||
/** @type {number} */ (part[0]),
|
contextScale,
|
||||||
/** @type {number} */ (part[1]),
|
/** @type {number} */ (part[0]),
|
||||||
label,
|
/** @type {number} */ (part[1]),
|
||||||
anchorX,
|
label,
|
||||||
anchorY,
|
anchorX,
|
||||||
declutterGroup,
|
anchorY,
|
||||||
label.height,
|
declutterGroup,
|
||||||
1,
|
label.height,
|
||||||
0,
|
1,
|
||||||
0,
|
0,
|
||||||
/** @type {number} */ (part[3]),
|
0,
|
||||||
pixelRatioScale,
|
/** @type {number} */ (part[3]),
|
||||||
false,
|
pixelRatioScale,
|
||||||
label.width,
|
false,
|
||||||
defaultPadding,
|
label.width,
|
||||||
null,
|
defaultPadding,
|
||||||
null
|
null,
|
||||||
);
|
null
|
||||||
|
) || rendered;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fillKey) {
|
if (fillKey) {
|
||||||
@@ -976,32 +989,35 @@ class Executor {
|
|||||||
label = this.createLabel(chars, textKey, fillKey, '');
|
label = this.createLabel(chars, textKey, fillKey, '');
|
||||||
anchorX = /** @type {number} */ (part[2]);
|
anchorX = /** @type {number} */ (part[2]);
|
||||||
anchorY = baseline * label.height - offsetY;
|
anchorY = baseline * label.height - offsetY;
|
||||||
this.replayImageOrLabel_(
|
rendered =
|
||||||
context,
|
this.replayImageOrLabel_(
|
||||||
contextScale,
|
context,
|
||||||
/** @type {number} */ (part[0]),
|
contextScale,
|
||||||
/** @type {number} */ (part[1]),
|
/** @type {number} */ (part[0]),
|
||||||
label,
|
/** @type {number} */ (part[1]),
|
||||||
anchorX,
|
label,
|
||||||
anchorY,
|
anchorX,
|
||||||
declutterGroup,
|
anchorY,
|
||||||
label.height,
|
declutterGroup,
|
||||||
1,
|
label.height,
|
||||||
0,
|
1,
|
||||||
0,
|
0,
|
||||||
/** @type {number} */ (part[3]),
|
0,
|
||||||
pixelRatioScale,
|
/** @type {number} */ (part[3]),
|
||||||
false,
|
pixelRatioScale,
|
||||||
label.width,
|
false,
|
||||||
defaultPadding,
|
label.width,
|
||||||
null,
|
defaultPadding,
|
||||||
null
|
null,
|
||||||
);
|
null
|
||||||
|
) || rendered;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (rendered) {
|
||||||
|
this.declutterItems.push(this, declutterGroup, feature);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.declutterItems.push(this, declutterGroup, feature);
|
|
||||||
++i;
|
++i;
|
||||||
break;
|
break;
|
||||||
case CanvasInstruction.END_GEOMETRY:
|
case CanvasInstruction.END_GEOMETRY:
|
||||||
|
|||||||
Reference in New Issue
Block a user