Add types and comments to make combined image+text decluttering clearer

This commit is contained in:
Andreas Hocevar
2020-10-05 15:21:40 +02:00
parent 187a216379
commit c9ebf79df5
6 changed files with 48 additions and 33 deletions

View File

@@ -100,15 +100,15 @@ class VectorContext {
/**
* @param {import("../style/Image.js").default} imageStyle Image style.
* @param {Object=} opt_sharedData Shared data for combined decluttering with a text style.
* @param {import("../render/canvas.js").DeclutterImageWithText=} opt_declutterImageWithText Shared data for combined decluttering with a text style.
*/
setImageStyle(imageStyle, opt_sharedData) {}
setImageStyle(imageStyle, opt_declutterImageWithText) {}
/**
* @param {import("../style/Text.js").default} textStyle Text style.
* @param {Object=} opt_sharedData Shared data for combined decluttering with an image style.
* @param {import("../render/canvas.js").DeclutterImageWithText=} opt_declutterImageWithText Shared data for combined decluttering with an image style.
*/
setTextStyle(textStyle, opt_sharedData) {}
setTextStyle(textStyle, opt_declutterImageWithText) {}
}
export default VectorContext;

View File

@@ -77,6 +77,10 @@ import {toString} from '../transform.js';
* @property {!Object<string, StrokeState>} [strokeStates] The stroke states (decluttering).
*/
/**
* @typedef {Object<number, import("./canvas/Executor.js").ReplayImageOrLabelArgs>} DeclutterImageWithText
*/
/**
* @const
* @type {string}

View File

@@ -49,6 +49,10 @@ import {transform2D} from '../../geom/flat/transform.js';
* @property {import("../../transform.js").Transform} canvasTransform
*/
/**
* @typedef {{0: CanvasRenderingContext2D, 1: number, 2: import("../canvas.js").Label|HTMLImageElement|HTMLCanvasElement|HTMLVideoElement, 3: ImageOrLabelDimensions, 4: number, 5: Array<*>, 6: Array<*>}} ReplayImageOrLabelArgs
*/
/**
* @type {import("../../extent.js").Extent}
*/
@@ -64,12 +68,11 @@ const p3 = [];
const p4 = [];
/**
* @param {Array<*>} replayImageOrLabelArgs Arguments to replayImageOrLabel
* @param {ReplayImageOrLabelArgs} replayImageOrLabelArgs Arguments to replayImageOrLabel
* @return {BBox} Declutter bbox.
*/
function getDeclutterBox(replayImageOrLabelArgs) {
return /** @type {ImageOrLabelDimensions} */ (replayImageOrLabelArgs[3])
.declutterBox;
return replayImageOrLabelArgs[3].declutterBox;
}
class Executor {
@@ -724,7 +727,7 @@ class Executor {
let rotation = /** @type {number} */ (instruction[11]);
const scale = /** @type {import("../../size.js").Size} */ (instruction[12]);
let width = /** @type {number} */ (instruction[13]);
const sharedData = instruction[14];
const declutterImageWithText = /** @type {import("../canvas.js").DeclutterImageWithText} */ (instruction[14]);
if (!image && instruction.length >= 19) {
// create label images
@@ -801,6 +804,7 @@ class Executor {
backgroundFill || backgroundStroke,
feature
);
/** @type {ReplayImageOrLabelArgs} */
const args = [
context,
contextScale,
@@ -816,13 +820,15 @@ class Executor {
];
let imageArgs;
let imageDeclutterBox;
if (opt_declutterTree && sharedData) {
if (!sharedData[d]) {
sharedData[d] = args;
if (opt_declutterTree && declutterImageWithText) {
if (!declutterImageWithText[d]) {
// We now have the image for an image+text combination.
declutterImageWithText[d] = args;
// Don't render anything for now, wait for the text.
continue;
}
imageArgs = sharedData[d];
delete sharedData[d];
imageArgs = declutterImageWithText[d];
delete declutterImageWithText[d];
imageDeclutterBox = getDeclutterBox(imageArgs);
if (opt_declutterTree.collides(imageDeclutterBox)) {
continue;
@@ -835,9 +841,11 @@ class Executor {
continue;
}
if (imageArgs) {
// We now have image and text for an image+text combination.
if (opt_declutterTree) {
opt_declutterTree.insert(imageDeclutterBox);
}
// Render the image before we render the text.
this.replayImageOrLabel_.apply(this, imageArgs);
}
if (opt_declutterTree) {
@@ -902,6 +910,7 @@ class Executor {
viewRotationFromTransform ? 0 : this.viewRotation_
);
drawChars: if (parts) {
/** @type {Array<ReplayImageOrLabelArgs>} */
const replayImageOrLabelArgs = [];
let c, cc, chars, label, part;
if (strokeKey) {

View File

@@ -95,9 +95,9 @@ class CanvasImageBuilder extends CanvasBuilder {
/**
* Data shared with a text builder for combined decluttering.
* @private
* @type {Object}
* @type {import("../canvas.js").DeclutterImageWithText}
*/
this.sharedData_ = undefined;
this.declutterImageWithText_ = undefined;
}
/**
@@ -132,7 +132,7 @@ class CanvasImageBuilder extends CanvasBuilder {
(this.scale_[1] * this.pixelRatio) / this.imagePixelRatio_,
],
Math.ceil(this.width_ * this.imagePixelRatio_),
this.sharedData_,
this.declutterImageWithText_,
]);
this.hitDetectionInstructions.push([
CanvasInstruction.DRAW_IMAGE,
@@ -150,7 +150,7 @@ class CanvasImageBuilder extends CanvasBuilder {
this.rotation_,
this.scale_,
this.width_,
this.sharedData_,
this.declutterImageWithText_,
]);
this.endGeometry(feature);
}
@@ -187,7 +187,7 @@ class CanvasImageBuilder extends CanvasBuilder {
(this.scale_[1] * this.pixelRatio) / this.imagePixelRatio_,
],
Math.ceil(this.width_ * this.imagePixelRatio_),
this.sharedData_,
this.declutterImageWithText_,
]);
this.hitDetectionInstructions.push([
CanvasInstruction.DRAW_IMAGE,
@@ -205,7 +205,7 @@ class CanvasImageBuilder extends CanvasBuilder {
this.rotation_,
this.scale_,
this.width_,
this.sharedData_,
this.declutterImageWithText_,
]);
this.endGeometry(feature);
}
@@ -255,7 +255,7 @@ class CanvasImageBuilder extends CanvasBuilder {
this.rotation_ = imageStyle.getRotation();
this.scale_ = imageStyle.getScaleArray();
this.width_ = size[0];
this.sharedData_ = opt_sharedData;
this.declutterImageWithText_ = opt_sharedData;
}
}

View File

@@ -142,9 +142,9 @@ class CanvasTextBuilder extends CanvasBuilder {
/**
* Data shared with an image builder for combined decluttering.
* @private
* @type {Object}
* @type {import("../canvas.js").DeclutterImageWithText}
*/
this.sharedData_ = undefined;
this.declutterImageWithText_ = undefined;
}
/**
@@ -335,7 +335,7 @@ class CanvasTextBuilder extends CanvasBuilder {
this.textRotation_,
[1, 1],
NaN,
this.sharedData_,
this.declutterImageWithText_,
padding == defaultPadding
? defaultPadding
: padding.map(function (p) {
@@ -367,7 +367,7 @@ class CanvasTextBuilder extends CanvasBuilder {
this.textRotation_,
[scale, scale],
NaN,
this.sharedData_,
this.declutterImageWithText_,
padding,
!!textState.backgroundFill,
!!textState.backgroundStroke,
@@ -586,7 +586,7 @@ class CanvasTextBuilder extends CanvasBuilder {
: '|' + getUid(fillState.fillStyle)
: '';
}
this.sharedData_ = opt_sharedData;
this.declutterImageWithText_ = opt_sharedData;
}
}

View File

@@ -346,10 +346,11 @@ function renderPointGeometry(
) {
const imageStyle = style.getImage();
const textStyle = style.getText();
let sharedData;
/** @type {import("../render/canvas.js").DeclutterImageWithText} */
let declutterImageWithText;
if (opt_declutterBuilderGroup) {
builderGroup = opt_declutterBuilderGroup;
sharedData =
declutterImageWithText =
imageStyle && textStyle && textStyle.getText() ? {} : undefined;
}
if (imageStyle) {
@@ -360,7 +361,7 @@ function renderPointGeometry(
style.getZIndex(),
BuilderType.IMAGE
);
imageReplay.setImageStyle(imageStyle, sharedData);
imageReplay.setImageStyle(imageStyle, declutterImageWithText);
imageReplay.drawPoint(geometry, feature);
}
if (textStyle && textStyle.getText()) {
@@ -368,7 +369,7 @@ function renderPointGeometry(
style.getZIndex(),
BuilderType.TEXT
);
textReplay.setTextStyle(textStyle, sharedData);
textReplay.setTextStyle(textStyle, declutterImageWithText);
textReplay.drawText(geometry, feature);
}
}
@@ -389,10 +390,11 @@ function renderMultiPointGeometry(
) {
const imageStyle = style.getImage();
const textStyle = style.getText();
let sharedData;
/** @type {import("../render/canvas.js").DeclutterImageWithText} */
let declutterImageWithText;
if (opt_declutterBuilderGroup) {
builderGroup = opt_declutterBuilderGroup;
sharedData =
declutterImageWithText =
imageStyle && textStyle && textStyle.getText() ? {} : undefined;
}
if (imageStyle) {
@@ -403,7 +405,7 @@ function renderMultiPointGeometry(
style.getZIndex(),
BuilderType.IMAGE
);
imageReplay.setImageStyle(imageStyle, sharedData);
imageReplay.setImageStyle(imageStyle, declutterImageWithText);
imageReplay.drawMultiPoint(geometry, feature);
}
if (textStyle && textStyle.getText()) {
@@ -411,7 +413,7 @@ function renderMultiPointGeometry(
style.getZIndex(),
BuilderType.TEXT
);
textReplay.setTextStyle(textStyle, sharedData);
textReplay.setTextStyle(textStyle, declutterImageWithText);
textReplay.drawText(geometry, feature);
}
}